/*!
 * AutoMedia — Member Dashboard ("produk SaaS premium" redesign of the
 * membership area). Separate app-like shell from the public reading site
 * (own sidebar/bottom-nav), same design tokens (tokens.css/components.css)
 * for brand + dark-mode consistency. Every section here either renders
 * real data (membership status, plans, transactions, personalized
 * recommendations reusing Fase 9's am_visitor-based engine) or an honestly
 * labeled "Segera Hadir" locked state — no fabricated numbers, matching
 * this project's "Unavailable" hook convention used everywhere else.
 */

/* =======================================================================
   Shell — sidebar (desktop) / bottom-nav + sticky CTA (mobile)
   ======================================================================= */
.member-shell { display: flex; min-height: 100vh; background: var(--color-bg-subtle); }

.member-sidebar {
    width: 264px;
    flex-shrink: 0;
    background: var(--color-surface);
    border-right: var(--border-width) solid var(--color-border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}
.member-sidebar__brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-5);
    font-weight: var(--font-bold);
    font-size: var(--text-lg);
    color: var(--color-text);
    text-decoration: none;
}
.member-sidebar__brand span { color: var(--color-accent); }
.member-nav { flex: 1; padding: var(--space-2) var(--space-3) var(--space-6); }
.member-nav-group__label {
    font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide);
    color: var(--color-text-tertiary); font-weight: var(--font-semibold);
    padding: var(--space-4) var(--space-3) var(--space-2);
}
.member-nav-link {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    text-decoration: none;
    position: relative;
    transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
}
.member-nav-link:hover { background: var(--color-bg-subtle); color: var(--color-text); }
.member-nav-link.is-active { background: var(--color-primary-subtle); color: var(--color-primary-subtle-text); font-weight: var(--font-semibold); }
.member-nav-link .icon { width: 18px; height: 18px; flex-shrink: 0; }
.member-nav-link__lock { margin-left: auto; width: 14px; height: 14px; color: var(--color-text-tertiary); flex-shrink: 0; }
/* "Notifikasi" unread badge (requested 2026-09-06) — same margin-left:
   auto trick as __lock above so it sits flush right regardless of label
   length, just a number instead of a lock icon. */
.member-nav-link__badge {
    margin-left: auto; flex-shrink: 0;
    background: var(--color-danger); color: white;
    font-size: 11px; font-weight: var(--font-semibold);
    min-width: 20px; height: 20px; padding: 0 6px;
    border-radius: var(--radius-full);
    display: inline-flex; align-items: center; justify-content: center;
}
.member-sidebar__foot { padding: var(--space-4) var(--space-5); border-top: var(--border-width) solid var(--color-border); }

.member-main { flex: 1; min-width: 0; }
.member-topbar {
    display: none;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-4);
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: var(--z-fixed);
}
.member-content { padding: var(--space-6) var(--space-8) var(--space-16); max-width: 1100px; margin: 0 auto; }
/* "Akun" topbar shortcut (moved here from the bottom nav, 2026-09-06) — same active-state color as every other member nav link. */
.member-topbar .btn--icon.is-active { background: var(--color-primary-subtle); color: var(--color-primary-subtle-text); }

@media (max-width: 1023px) {
    .member-sidebar { display: none; }
    .member-topbar { display: flex; }
    /* A page's own <h1>/subtitle duplicates the title `.member-topbar`
       already shows once it takes over on mobile (requested directly,
       2026-09-06, for "Tulis Berita") — reusable on any member page's
       heading block, not a one-off inline style. */
    .member-page-heading { display: none; }
    .member-content { padding: var(--space-5) var(--space-4) var(--space-24); }
}

/* Mobile bottom nav — curated 5-item subset, not the full sidebar */
.member-bottom-nav {
    display: none;
    position: fixed; left: 0; right: 0; bottom: 0;
    z-index: var(--z-fixed);
    background: color-mix(in srgb, var(--color-surface) 94%, transparent);
    backdrop-filter: blur(10px);
    border-top: var(--border-width) solid var(--color-border);
    padding: var(--space-1) var(--space-2);
    padding-bottom: calc(var(--space-1) + env(safe-area-inset-bottom));
}
@media (max-width: 1023px) {
    .member-bottom-nav { display: flex; justify-content: space-around; }
}
.member-bottom-nav__item {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: var(--space-1) var(--space-2);
    color: var(--color-text-tertiary);
    text-decoration: none;
    font-size: 11px;
}
.member-bottom-nav__item.is-active { color: var(--color-primary); }
.member-bottom-nav__item .icon { width: 20px; height: 20px; }

/* "Buat Berita" FAB — a real flex child in the SAME .member-bottom-nav
   row as the .member-bottom-nav__item links (rendered at the middle
   index by member/layout.php), not overlaid on top of them, so
   space-around divides the bar into N+1 even columns instead of
   overlaying an independently-centered element on top of an N-column
   split (fixed a text-collision bug this way, 2026-09-06). That first
   fix made the FAB's own full content height (icon + label, ~70px) count
   toward the flex row's height like any other item, which made the whole
   sticky bar noticeably taller than the ordinary item row needed
   (reported directly, same day: "height stickynya terlalu tinggi").
   Fixed by keeping the ANCHOR's own in-flow box the same height as a
   `.member-bottom-nav__item` (padding-top reserves just enough room for
   the label) while the raised circle icon is pulled out of flow with its
   own `position: absolute` *inside* that anchor — it still visually
   pokes up above the bar exactly like before, it just no longer inflates
   the row's computed height. */
.member-bottom-nav__fab {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
    padding: 26px var(--space-2) var(--space-1);
    text-decoration: none;
}
.member-bottom-nav__fab-icon {
    position: absolute;
    top: -20px; left: 50%;
    transform: translateX(-50%);
    width: 46px; height: 46px;
    border-radius: var(--radius-full);
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--ink-700), var(--signal-600));
    color: white;
    border: 3px solid var(--color-surface); /* separates the raised circle from the bar behind it */
    box-shadow: var(--shadow-lg);
}
.member-bottom-nav__fab-icon .icon { width: 22px; height: 22px; }
.member-bottom-nav__fab-label { font-size: 11px; font-weight: var(--font-semibold); color: var(--color-primary); }
.member-bottom-nav__fab.is-active .member-bottom-nav__fab-icon { box-shadow: var(--shadow-lg), 0 0 0 3px var(--color-primary-subtle); }

/* Sticky upgrade CTA — mobile only, sits above the bottom nav, same
   stacking pattern as article.css's .floating-actions */
.member-sticky-cta {
    display: none;
    position: fixed; left: var(--space-3); right: var(--space-3);
    bottom: calc(64px + var(--space-3));
    z-index: var(--z-fixed);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-full);
    background: linear-gradient(135deg, var(--ink-700), var(--signal-600));
    color: white;
    box-shadow: var(--shadow-lg);
    text-decoration: none;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    font-weight: var(--font-semibold);
    font-size: var(--text-sm);
}
@media (max-width: 1023px) {
    .member-sticky-cta.is-visible { display: flex; }
}

/* =======================================================================
   Header block — avatar, name, level, join date, expiry, progress
   ======================================================================= */
.member-header { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-6); flex-wrap: wrap; }
.member-header__avatar {
    width: 56px; height: 56px; border-radius: var(--radius-full);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--text-xl); font-weight: var(--font-bold);
    background: linear-gradient(135deg, var(--ink-600), var(--signal-500));
    color: white;
    flex-shrink: 0;
}
.member-header__name { font-size: var(--text-xl); font-weight: var(--font-bold); margin: 0; }
.member-header__meta { color: var(--color-text-secondary); font-size: var(--text-sm); display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.member-header__actions { margin-left: auto; }

/* =======================================================================
   Membership card — the centerpiece. Two visual states: active premium
   (gradient, celebratory) vs free/expired (muted, upgrade-oriented) —
   deliberately different so the card itself communicates status at a
   glance, not just its text.
   ======================================================================= */
.membership-card {
    border-radius: var(--radius-xl);
    padding: var(--space-8);
    margin-bottom: var(--space-6);
    position: relative;
    overflow: hidden;
}
.membership-card--active {
    background: linear-gradient(135deg, var(--ink-800) 0%, var(--ink-600) 55%, var(--signal-600) 100%);
    color: white;
    box-shadow: var(--shadow-lg);
}
.membership-card--active::before {
    content: "";
    position: absolute; top: -40%; right: -10%;
    width: 320px; height: 320px;
    background: radial-gradient(circle, hsla(0, 0%, 100%, 0.14), transparent 70%);
    pointer-events: none;
}
.membership-card--inactive {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
}
.membership-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; position: relative; z-index: 1; }
.membership-card__plan { font-size: var(--text-2xl); font-weight: var(--font-bold); margin: 0 0 var(--space-1); }
.membership-card__sub { opacity: 0.85; font-size: var(--text-sm); }
.membership-card--inactive .membership-card__sub { opacity: 1; color: var(--color-text-secondary); }
.membership-card__grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--space-4); margin: var(--space-6) 0; position: relative; z-index: 1;
}
.membership-card__grid-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); opacity: 0.75; margin-bottom: 2px; }
.membership-card__grid-value { font-size: var(--text-base); font-weight: var(--font-semibold); }
.membership-card__actions { display: flex; gap: var(--space-3); flex-wrap: wrap; position: relative; z-index: 1; }
.membership-card--active .btn--secondary { background: hsla(0, 0%, 100%, 0.14); color: white; border-color: hsla(0, 0%, 100%, 0.3); }
.membership-card--active .btn--secondary:hover { background: hsla(0, 0%, 100%, 0.22); }

/* Progress bar — days remaining out of the plan's total duration */
.member-progress { margin-top: var(--space-5); position: relative; z-index: 1; }
.member-progress__track { height: 8px; border-radius: var(--radius-full); background: hsla(0, 0%, 100%, 0.18); overflow: hidden; }
.membership-card--inactive .member-progress__track { background: var(--color-bg-subtle); }
.member-progress__fill {
    height: 100%; border-radius: var(--radius-full);
    background: white;
    transition: width var(--duration-slow) var(--ease-decelerate);
}
.membership-card--inactive .member-progress__fill { background: var(--color-primary); }
.member-progress__label { font-size: var(--text-xs); margin-top: var(--space-2); opacity: 0.85; }

/* =======================================================================
   Benefit grid
   ======================================================================= */
.benefit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-4); margin: var(--space-5) 0 var(--space-8); }
.benefit-card {
    display: flex; gap: var(--space-3); align-items: flex-start;
    padding: var(--space-5); border-radius: var(--radius-lg);
    background: var(--color-surface); border: var(--border-width) solid var(--color-border);
    transition: transform var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.benefit-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.benefit-card__icon {
    width: 44px; height: 44px; border-radius: var(--radius-md); flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--color-accent-subtle); color: var(--color-accent-subtle-text);
}
.benefit-card__icon .icon { width: 22px; height: 22px; }
.benefit-card__title { font-weight: var(--font-semibold); margin: 0 0 2px; }
.benefit-card__desc { font-size: var(--text-sm); color: var(--color-text-secondary); margin: 0; }

/* =======================================================================
   Why upgrade — dark contrast band, mirrors the pattern premium SaaS
   marketing sections use to break up an otherwise all-white page
   ======================================================================= */
.why-upgrade {
    border-radius: var(--radius-xl);
    padding: var(--space-8);
    margin: var(--space-8) 0;
    background: linear-gradient(135deg, var(--ink-800), var(--ink-700));
    color: white;
}
.why-upgrade__title { font-size: var(--text-2xl); font-weight: var(--font-bold); margin: 0 0 var(--space-5); }
.why-upgrade__list { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-3); list-style: none; margin: 0; padding: 0; }
.why-upgrade__list li { display: flex; align-items: flex-start; gap: var(--space-2); font-size: var(--text-sm); opacity: 0.92; }
.why-upgrade__list .icon { width: 18px; height: 18px; flex-shrink: 0; margin-top: 2px; color: var(--signal-400); }

/* =======================================================================
   Pricing grid
   ======================================================================= */
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-5); margin: var(--space-5) 0; }
.pricing-plan {
    border-radius: var(--radius-xl);
    padding: var(--space-6);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    display: flex; flex-direction: column;
    transition: transform var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.pricing-plan:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.pricing-plan--highlight {
    border-color: transparent;
    background: linear-gradient(var(--color-surface), var(--color-surface)) padding-box,
                linear-gradient(135deg, var(--ink-600), var(--signal-500)) border-box;
    border: 2px solid transparent;
    box-shadow: var(--shadow-lg);
    position: relative;
}
.pricing-plan__badge {
    align-self: flex-start;
    background: linear-gradient(135deg, var(--ink-600), var(--signal-500));
    color: white; font-size: var(--text-xs); font-weight: var(--font-semibold);
    padding: 3px var(--space-3); border-radius: var(--radius-full); margin-bottom: var(--space-3);
}
.pricing-plan__name { font-size: var(--text-lg); font-weight: var(--font-bold); margin: 0 0 var(--space-1); }
.pricing-plan__price { font-size: var(--text-3xl); font-weight: var(--font-bold); margin: var(--space-2) 0 0; }
.pricing-plan__price small { font-size: var(--text-sm); font-weight: var(--font-normal); color: var(--color-text-tertiary); }
.pricing-plan__duration { font-size: var(--text-sm); color: var(--color-text-tertiary); margin-bottom: var(--space-4); }
.pricing-plan__desc { font-size: var(--text-sm); color: var(--color-text-secondary); flex: 1; margin-bottom: var(--space-5); }
.pricing-plan .btn { width: 100%; }

/* =======================================================================
   Coming-soon locked section — honest placeholder, not fake data.
   Reused for every sidebar item without a real backend yet.
   ======================================================================= */
.coming-soon {
    text-align: center;
    padding: var(--space-16) var(--space-6);
    border-radius: var(--radius-xl);
    border: 2px dashed var(--color-border);
    background: var(--color-surface);
}
.coming-soon__icon {
    width: 64px; height: 64px; border-radius: var(--radius-full);
    display: flex; align-items: center; justify-content: center;
    background: var(--color-bg-subtle); color: var(--color-text-tertiary);
    margin: 0 auto var(--space-5);
}
.coming-soon__icon .icon { width: 30px; height: 30px; }
.coming-soon__title { font-size: var(--text-lg); font-weight: var(--font-semibold); margin: 0 0 var(--space-2); }
.coming-soon__desc { color: var(--color-text-secondary); max-width: 32rem; margin: 0 auto; }
.coming-soon__badge {
    display: inline-block; margin-top: var(--space-4);
    font-size: var(--text-xs); font-weight: var(--font-semibold); text-transform: uppercase; letter-spacing: var(--tracking-wide);
    color: var(--color-text-tertiary); background: var(--color-bg-subtle);
    border: var(--border-width) solid var(--color-border); border-radius: var(--radius-full);
    padding: var(--space-1) var(--space-4);
}

/* =======================================================================
   Payment status / gateway honesty banner
   ======================================================================= */
.payment-status {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-5);
    font-size: var(--text-sm);
}
.payment-status--unavailable { background: var(--color-warning-subtle); color: var(--color-warning-subtle-text); }
.payment-status--ok { background: var(--color-success-subtle); color: var(--color-success-subtle-text); }
.payment-status .icon { width: 20px; height: 20px; flex-shrink: 0; }

/* =======================================================================
   Small section heading used across member pages
   ======================================================================= */
.member-section-title { font-size: var(--text-xl); font-weight: var(--font-bold); margin: var(--space-8) 0 var(--space-2); }
.member-section-sub { color: var(--color-text-secondary); font-size: var(--text-sm); margin: 0 0 var(--space-5); }

/* Recommended articles — thin horizontal cards reusing .card patterns */
.reco-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-4); }

/* =======================================================================
   Reward Point program (requested 2026-09-06) — a member's points balance
   hero (dashboard summary + rewards.php's own bigger header) and the
   "Tulis Berita, dapat poin!" incentive banner reused on both the
   submissions list and the write-article wizard. Balance hero reuses the
   membership-card--active gradient so it reads as the same tier of "big
   number, look at me" UI the membership card already established.
   ======================================================================= */
.points-hero {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    border-radius: var(--radius-xl);
    padding: var(--space-6) var(--space-8);
    margin-bottom: var(--space-6);
    background: linear-gradient(135deg, var(--ink-800) 0%, var(--ink-600) 55%, var(--signal-600) 100%);
    color: white;
    box-shadow: var(--shadow-lg);
    text-decoration: none;
}
.points-hero--link { transition: transform 0.15s ease; }
.points-hero--link:hover { transform: translateY(-2px); }
.points-hero__label { font-size: var(--text-sm); opacity: 0.85; margin-bottom: var(--space-1); }
.points-hero__value { font-size: var(--text-3xl); font-weight: var(--font-bold); }
.points-hero__value span { font-size: var(--text-base); font-weight: var(--font-normal); opacity: 0.85; }
.points-hero__icon { width: 40px; height: 40px; opacity: 0.5; flex-shrink: 0; }

.reward-cta {
    display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
    padding: var(--space-5); border-radius: var(--radius-lg);
    background: var(--color-accent-subtle); color: var(--color-accent-subtle-text);
}
.reward-cta > .icon { width: 28px; height: 28px; flex-shrink: 0; }
.reward-cta > div { flex: 1; min-width: 200px; }
.reward-cta strong { display: block; margin-bottom: 2px; }
.reward-cta p { margin: 0; font-size: var(--text-sm); opacity: 0.9; }
/* Compact one-line variant, shown only < 1024px (requested directly,
   2026-09-06: the full sentence wrapped to 3-4 lines on a narrow phone,
   "boros height") — a separate short `<p class="reward-cta__desc--compact">`
   sits alongside the existing full one rather than truncating it with
   line-clamp, since clamping would risk cutting off the "Poin Saya" link
   itself partway through the sentence depending on exact device width.
   `.reward-cta__desc--compact` is authored right after the full
   paragraph in each view, so no markup duplication logic is needed here
   beyond which one each breakpoint shows. */
.reward-cta__desc--compact { display: none; }
@media (max-width: 1023px) {
    .reward-cta { padding: var(--space-3) var(--space-4); gap: var(--space-3); }
    .reward-cta > .icon { width: 20px; height: 20px; }
    .reward-cta strong { font-size: var(--text-sm); margin-bottom: 0; }
    .reward-cta p:not(.reward-cta__desc--compact) { display: none; }
    .reward-cta__desc--compact { display: block; font-size: var(--text-xs); }
}

.reward-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-5); margin: var(--space-5) 0 var(--space-8); }
.reward-card {
    border-radius: var(--radius-xl);
    background: var(--color-surface); border: var(--border-width) solid var(--color-border);
    overflow: hidden;
    display: flex; flex-direction: column;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.reward-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.reward-card__image { width: 100%; aspect-ratio: 16/10; object-fit: cover; background: var(--color-bg-subtle); }
.reward-card__image--placeholder { display: flex; align-items: center; justify-content: center; color: var(--color-text-tertiary); }
.reward-card__image--placeholder .icon { width: 32px; height: 32px; }
.reward-card__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.reward-card__name { font-weight: var(--font-semibold); }
.reward-card__desc { font-size: var(--text-sm); color: var(--color-text-secondary); margin: 0; flex: 1; }
.reward-card__cost { font-size: var(--text-lg); font-weight: var(--font-bold); color: var(--color-primary); }
.reward-card__body .btn, .reward-card__body form { width: 100%; }

@media (prefers-reduced-motion: reduce) {
    .benefit-card, .pricing-plan, .member-progress__fill, .points-hero--link, .reward-card { transition: none; }
}

/* =======================================================================
   "Buat Berita" 3-step timeline wizard (member/news-submission-form.php)
   ======================================================================= */
.wizard-steps {
    display: flex; list-style: none; margin: 0 0 var(--space-8); padding: 0;
}
.wizard-steps__item {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
    text-align: center; font-size: var(--text-xs); color: var(--color-text-tertiary);
    position: relative;
}
/* Connecting line between step circles — drawn behind them via a
   full-width pseudo-element on each item except the first, so it's
   trivially centered regardless of container width. */
.wizard-steps__item:not(:first-child)::before {
    content: ''; position: absolute; top: 15px; right: 50%; width: 100%; height: 2px;
    background: var(--color-border); z-index: 0;
}
.wizard-steps__item.is-done:not(:first-child)::before,
.wizard-steps__item.is-active:not(:first-child)::before { background: var(--color-primary); }
.wizard-steps__num {
    width: 32px; height: 32px; border-radius: var(--radius-full);
    display: flex; align-items: center; justify-content: center;
    font-weight: var(--font-bold); background: var(--color-bg-subtle); color: var(--color-text-tertiary);
    border: 2px solid var(--color-border);
    position: relative; z-index: 1;
}
.wizard-steps__item.is-active .wizard-steps__num { background: var(--color-primary); border-color: var(--color-primary); color: white; }
.wizard-steps__item.is-active { color: var(--color-primary); font-weight: var(--font-semibold); }
.wizard-steps__item.is-done .wizard-steps__num { background: var(--color-success); border-color: var(--color-success); color: white; }
.wizard-steps__item.is-done { color: var(--color-text); }

.wizard-actions { display: flex; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-6); }

/* Step 1 — photo capture/upload. Redesigned (requested directly,
   2026-09-06: "upload fotonya sekeren instagram") as ONE tap target —
   the previous version showed this pretty frame AND the browser's own
   native file-input control below it at the same time, reported as
   looking "kacau". The real <input type="file"> is now `.sr-only`
   (visually hidden but still focusable/label-triggerable — NOT
   `display:none`, which some older browsers refuse to trigger via a
   <label for>) and the whole frame is the single <label>; every visual
   state (empty / filled / hover) lives on the frame itself. */
.photo-upload { max-width: 420px; margin: 0 auto var(--space-4); }
.photo-upload__frame {
    position: relative;
    display: block;
    width: 100%; aspect-ratio: 4 / 3;
    border: 2px dashed var(--color-border-strong); border-radius: var(--radius-xl);
    background: var(--color-bg-subtle);
    overflow: hidden;
    cursor: pointer;
    transition: border-color var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
.photo-upload__frame:hover { border-color: var(--color-primary); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.photo-upload__frame--filled { border-style: solid; border-color: var(--color-border); }
.photo-upload__frame img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover;
}
.photo-upload__empty {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1);
    padding: var(--space-6);
    text-align: center;
    color: var(--color-text-tertiary);
}
.photo-upload__empty strong { color: var(--color-text); font-size: var(--text-base); }
.photo-upload__empty span:last-child { font-size: var(--text-sm); }
.photo-upload__empty-icon {
    width: 56px; height: 56px; margin-bottom: var(--space-2);
    border-radius: var(--radius-full);
    background: var(--color-surface);
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-sm);
}
.photo-upload__empty-icon .icon { width: 26px; height: 26px; color: var(--color-primary); }
/* Bottom gradient bar over the filled preview — same "tap to change"
   affordance Instagram/every modern photo picker uses instead of a
   second visible control next to the image. Plain <span>s only (no
   nested <button>) so a click still bubbles up to the <label>'s own
   default action instead of a nested control intercepting it. */
.photo-upload__overlay {
    position: absolute; left: 0; right: 0; bottom: 0;
    display: flex; justify-content: center;
    padding: var(--space-8) var(--space-4) var(--space-4);
    background: linear-gradient(to top, hsla(0, 0%, 0%, 0.55), transparent);
}
.photo-upload__overlay-btn {
    display: inline-flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-full);
    background: hsla(0, 0%, 100%, 0.92);
    color: var(--color-text);
    font-size: var(--text-sm); font-weight: var(--font-semibold);
}
.photo-upload__overlay-btn .icon { width: 16px; height: 16px; }
.photo-upload__remove {
    display: flex; align-items: center; justify-content: center; gap: var(--space-2);
    width: 100%; margin-top: var(--space-3);
    padding: var(--space-2);
    border: none; background: none; cursor: pointer;
    font-size: var(--text-sm); font-weight: var(--font-medium);
    color: var(--color-danger-subtle-text);
}
.photo-upload__remove .icon { width: 16px; height: 16px; }
.photo-upload__status { text-align: center; font-size: var(--text-sm); min-height: 1.4em; margin: var(--space-2) 0 0; color: var(--color-text-tertiary); }
.photo-upload__status--success { color: var(--color-success-subtle-text); }
.photo-upload__status--danger { color: var(--color-danger-subtle-text); }

/* Step 2 — AI-assist callout */
.ai-generate-box {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap;
    background: var(--color-primary-subtle); border-radius: var(--radius-lg);
    padding: var(--space-4) var(--space-5); margin-bottom: var(--space-2);
}

/* Step 3 — article-like preview, deliberately mirroring the real public
   article layout's typographic scale (Views/web/news/show.php) so what a
   member sees here is an honest approximation of what will actually
   render once published — not a generic form summary. */
.article-preview { max-width: 640px; }
.article-preview img { width: 100%; border-radius: var(--radius-lg); margin-bottom: var(--space-4); }
.article-preview__category { font-size: var(--text-xs); font-weight: var(--font-semibold); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--color-primary); margin-bottom: var(--space-2); }
.article-preview__title { font-size: var(--text-2xl); font-weight: var(--font-bold); line-height: 1.25; margin: 0 0 var(--space-3); }
.article-preview__excerpt { font-size: var(--text-lg); color: var(--color-text-secondary); margin: 0 0 var(--space-5); }
.article-preview__content { white-space: pre-line; line-height: 1.7; color: var(--color-text); }
