/* ════════════════════════════════════════════════════════════════════
   DASHBOARD SHELL — the single shared application frame for every
   /dashboard/* route (overview, applications, builder, settings).
   The sidebar + mobile drawer markup is injected once by
   /assets/js/dashboard-shell.js; this file is its only styling source.
   Loaded by every dashboard page so the frame is byte-identical and
   never re-authored per page. Page-specific content styles stay inline
   on each page.
   ════════════════════════════════════════════════════════════════════ */

html, body { overflow-x: clip; }

/* Refined scrollbars — a premium-desktop-app detail. Standard property on the
   document (keeps the native width for usability); thin styled bars on inner
   scrollables (the mobile drawer). Firefox: scrollbar-color; WebKit below. */
html { scrollbar-color: rgba(255,255,255,.22) transparent; }
.side { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.18) transparent; }
.side::-webkit-scrollbar { width: 8px; }
.side::-webkit-scrollbar-thumb { background: rgba(255,255,255,.16); border-radius: 99px; border: 2px solid transparent; background-clip: content-box; }
.side::-webkit-scrollbar-track { background: transparent; }

/* ════════════════════════════════════════════════════════════════════
   PRE-PAINT AUTH GATE
   Hide the protected shell until /assets/js/auth-gate.js confirms a valid
   session, so an unauthenticated visitor (or a bfcache restore after logout)
   never sees a flash of protected content before the redirect. The static
   `bh-auth-pending` class ships in each protected page's <html>, so the hide
   is in effect from the very first paint; the gate removes it on success or
   redirects while still hidden. An opaque cover + spinner give a clean loading
   state instead of a blank screen for the (fast) authed path.
   ════════════════════════════════════════════════════════════════════ */
html.bh-auth-pending body { visibility: hidden; }
html.bh-auth-pending::before {
  content: ""; position: fixed; inset: 0;
  /* Match the real page background (#0a0908) so revealing the shell never
     jumps from a lighter loading shade to the darker page. */
  background: #0a0908; z-index: 2147483646;
}
html.bh-auth-pending::after {
  content: ""; position: fixed; inset: 0; margin: auto;
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .16);
  border-top-color: #e8a85e;
  animation: bhAuthSpin .7s linear infinite;
  z-index: 2147483647;
}
@keyframes bhAuthSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  html.bh-auth-pending::after { animation: none; border-top-color: rgba(255, 255, 255, .16); }
}

/* ── Gate states injected by auth-gate.js ──────────────────────────────
   Both live under the pre-paint cover while <body> is hidden, so they carry
   `visibility: visible` explicitly and use literal palette values (they must
   render even if a theme sheet failed). */

/* Quiet caption under the spinner for a slow cold session check (~900ms+). */
.bh-gate-caption {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, 40px);
  z-index: 2147483647; visibility: visible;
  font: 500 .86rem/1.5 'Schibsted Grotesk', system-ui, sans-serif;
  color: #8a8378; letter-spacing: .01em; white-space: nowrap;
}

/* Session interstitial — the designed terminal state for "no identity and the
   session could not be confirmed". Replaces the old bare reveal of a dead
   skeleton shell. The spinner hides; the dark cover stays. */
html.bh-gate-stuck::after { content: none; }
.bh-gate-fallback {
  position: fixed; inset: 0; z-index: 2147483647; visibility: visible;
  display: grid; place-items: center; padding: 24px;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
}
.bh-gate-card {
  width: min(430px, 100%); box-sizing: border-box;
  padding: 30px 28px 28px; border-radius: 22px; text-align: center;
  background: rgba(255,255,255,.035);
  border: 1px solid rgba(255,255,255,.11);
  box-shadow: 0 26px 64px rgba(0,0,0,.46), inset 0 1px 0 rgba(255,255,255,.08);
  color: #f4f1ec;
}
.bh-gate-brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: .95rem; letter-spacing: -.02em;
}
.bh-gate-brand i {
  width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center;
  font-style: normal; color: #2a1c0c;
  background: linear-gradient(180deg, #f3bd78, #c8843a);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5);
}
/* The mark sits at 58% of the tile, the same ratio every other .brand-mark uses. */
.bh-gate-brand i svg { width: 58%; height: auto; display: block; }
.bh-gate-held { color: #e8a85e; }
.bh-gate-card h2 { margin: 18px 0 0; font-size: 1.28rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; }
.bh-gate-card p { margin: 10px auto 0; max-width: 36ch; color: #b9b2a8; font-size: .9rem; line-height: 1.55; }
.bh-gate-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 22px; }
.bh-gate-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 12px 22px; border-radius: 12px;
  font: 600 .9rem/1 'Schibsted Grotesk', system-ui, sans-serif;
  color: #f4f1ec; background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.16); cursor: pointer;
  transition: background .18s, border-color .18s, transform .18s, box-shadow .18s;
  touch-action: manipulation;
}
.bh-gate-btn:where(:hover) { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.26); } /* §btn-variant-hover */
.bh-gate-btn:active { transform: scale(.985); }
.bh-gate-btn:focus-visible { outline: 2px solid rgba(232,168,94,.7); outline-offset: 2px; }
.bh-gate-btn--primary {
  color: #2a1c0c; background: linear-gradient(180deg, #f3bd78, #c8843a);
  border-color: rgba(255,255,255,.18);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 0 26px rgba(232,168,94,.14);
}
.bh-gate-btn--primary:hover { background: linear-gradient(180deg, #f7c98b, #d08e42); box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 0 30px rgba(232,168,94,.22); } /* §btn-variant-hover */
@media (prefers-reduced-motion: reduce) {
  .bh-gate-btn, .bh-gate-btn:active { transition: none; transform: none; }
}

/* App grid: persistent 272px sidebar + fluid content */
/* 100dvh = dynamic viewport height (excludes iOS browser chrome like the address bar).
   Falls back to 100vh on older browsers. Without dvh, the app grid overflows the visible
   area on iOS Safari when the address bar is showing, causing layout issues. */
.app { display: grid; grid-template-columns: 272px 1fr; gap: 18px; padding: 18px; min-height: 100vh; min-height: 100dvh; align-items: start; }

/* ── Sidebar ── */
/* height: 100dvh (dynamic viewport height) so the sidebar fills only the truly visible
   area on iOS Safari, not the area behind the browser toolbar.
   will-change:transform and contain:paint were previously here for backdrop-filter
   resampling but on iOS Safari they break position:sticky — the element is composited
   to its own layer, and WebKit's sticky implementation doesn't correctly apply the
   sticky constraint to independently-composited layers on some iOS versions, causing
   the sidebar to scroll instead of staying fixed. Removed; the backdrop-filter
   resampling cost on desktop is acceptable without them. */
.side { position: sticky; top: 18px; display: flex; flex-direction: column; padding: 16px; height: calc(100vh - 36px); height: calc(100dvh - 36px); }

/* Profile card */
.side-profile { padding: 14px 14px 12px; border-radius: var(--r-sm); background: rgba(255,255,255,.03); border: 1px solid var(--glass-border); margin-bottom: 6px; }
.sp-top { display: flex; align-items: center; gap: 11px; margin-bottom: 10px; }
.ava { width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; font-weight: 800; color: var(--amber-ink); background: linear-gradient(180deg,var(--amber-bright),var(--amber-deep)); box-shadow: inset 0 1px 0 rgba(255,255,255,.5); flex: none; font-size: .9rem; }
.sp-text { flex: 1; min-width: 0; }
.sp-name { font-weight: 700; font-size: .94rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.2; }
.sp-email-row { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 7px; background: rgba(0,0,0,.18); border: 1px solid rgba(255,255,255,.07); }
.sp-email-icon { flex: none; color: var(--ink-faint); }
.sp-email { font-size: .75rem; color: var(--ink-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; cursor: default; letter-spacing: .01em; line-height: 1; }
.side-sep { border: none; border-top: 1px solid var(--glass-border); margin: 4px 0; }
.side-nav { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; }
/* Nav micro-interactions (§dash-craft): token-driven state flips, the icon
   answers the hover (warms + nudges toward the destination), and a press
   registers instantly — the sidebar is the app's most-touched control. */
.side-nav a { display: flex; align-items: center; gap: 11px; padding: 11px 13px; border-radius: var(--r-sm); color: var(--ink-soft); text-decoration: none; font-size: .92rem; font-weight: 500; transition: background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.side-nav a svg { width: 17px; height: 17px; opacity: .8; flex: none; transition: opacity var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), transform var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.side-nav a:hover { color: var(--ink); background: rgba(255,255,255,.04); }
@media (hover: hover) and (pointer: fine) {
  .side-nav a:hover svg { opacity: 1; transform: translateX(1px); }
}
.side-nav a:active { background: rgba(255,255,255,.07); transition-duration: var(--dur-fast, .12s); }
.side-nav a.active { color: var(--ink); background: linear-gradient(180deg,rgba(232,168,94,.2),rgba(232,168,94,.06)); border: 1px solid rgba(232,168,94,.28); box-shadow: inset 0 1px 0 rgba(255,255,255,.12); }
.side-nav a.active svg { color: var(--amber); opacity: 1; }
/* Locked (premium) nav item — discoverable upgrade prompt; still navigable */
.side-nav a .nav-lock { margin-left: auto; display: inline-flex; align-items: center; color: var(--amber); opacity: .85; }
.side-nav a .nav-lock svg { width: 13px; height: 13px; opacity: 1; }
.side-nav a.nav-locked .t-en, .side-nav a.nav-locked .t-de { opacity: .82; }
/* Visually-hidden "(locked)" text so assistive tech announces the gated state
   (the lock icon is aria-hidden and a title attribute is not reliably read). */
.nav-lock-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
/* Nav item descriptor (§H1) — disambiguates CV Builder (AI) from Studio (manual). */
.side-nav a .nav-tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.side-nav a .nav-main { line-height: 1.2; }
.side-nav a .nav-sub { font-size: .72rem; font-weight: 500; line-height: 1.2; color: var(--ink-mute); letter-spacing: .005em; transition: color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.side-nav a:hover .nav-sub, .side-nav a.active .nav-sub { color: var(--ink-soft); }
.side-bottom { margin-top: auto; }

/* Credits widget — whole card links to /dashboard/billing */
.plan-widget { display: block; text-decoration: none; color: inherit; cursor: pointer; padding: 12px 14px; border-radius: var(--r-sm); background: rgba(232,168,94,.04); border: 1px solid rgba(232,168,94,.22); transition: background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), border-color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), transform var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.plan-widget:hover { background: rgba(232,168,94,.08); border-color: rgba(232,168,94,.45); }
@media (hover: hover) and (pointer: fine) { .plan-widget:hover { transform: translateY(-1px); } }
.plan-widget:active { transform: translateY(0) scale(.99); transition-duration: var(--dur-fast, .12s); }
.plan-widget:focus-visible { outline: 2px solid rgba(232,168,94,.7); outline-offset: 2px; }
.plan-widget-label { font-family: 'JetBrains Mono',monospace; font-size: .63rem; letter-spacing: .10em; text-transform: uppercase; color: var(--ink-mute); margin-bottom: 8px; display: block; }
/* Three-resource balance rows (§commerce-impl): Bewerbungen / Analysen / Exporte
   remaining, from auth-me `resources`. Replaces the single used% bar. */
.pw-res-rows { display: flex; flex-direction: column; gap: 3px; margin-bottom: 10px; }
.pw-res-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: .78rem; color: var(--ink-soft); }
.pw-res-row b { font-family: 'JetBrains Mono',monospace; font-size: .8rem; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.pw-res-row.depleted b { color: var(--ink-mute); }
.pw-res-empty { font-size: .76rem; color: var(--ink-mute); display: block; }
.pw-upgrade-btn { display: block; text-align: center; font-size: .81rem; font-weight: 500; padding: 8px 12px; border-radius: var(--r-sm); background: rgba(232,168,94,.10); border: 1px solid rgba(232,168,94,.32); color: var(--amber); text-decoration: none; transition: background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), border-color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.pw-upgrade-btn:hover { background: rgba(232,168,94,.18); border-color: rgba(232,168,94,.52); }
/* Logout — canonical soft-red sign-out language (matches the public .m-menu
   logout: #f0a89f text + red-tint hover), so it reads as a distinct,
   deliberate action instead of disappearing into the muted grays. */
.pw-logout-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; margin-top: 6px; padding: 9px 12px; font-size: .8rem; font-weight: 500; color: #f0a89f; background: none; border: none; cursor: pointer; font-family: inherit; border-radius: var(--r-sm); transition: color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); touch-action: manipulation; }
.pw-logout-btn svg { width: 15px; height: 15px; flex: none; opacity: .9; }
.pw-logout-btn:hover { color: #f6beb6; background: rgba(232,137,126,.10); }
/* Help & feedback (§feedback) — deliberately the QUIETEST thing in the sidebar.
   It must be reachable from every page, and it must never look like the product
   expects you to need it. Muted gray, no border, below the nav, above logout. */
.pw-help-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; margin-top: 8px; padding: 9px 12px; font-size: .8rem; font-weight: 500; color: var(--ink-mute); background: none; border: none; cursor: pointer; font-family: inherit; border-radius: var(--r-sm); transition: color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); touch-action: manipulation; }
.pw-help-btn svg { width: 15px; height: 15px; flex: none; opacity: .85; }
.pw-help-btn:hover { color: var(--ink-soft); background: rgba(255,255,255,.05); }
.pw-help-btn:active { transform: scale(.98); transition-duration: var(--dur-fast, .12s); }

/* ── Content area ── */
.main { padding-block: 6px; min-width: 0; }
.topbar { display: flex; align-items: center; padding: 4px 6px 0; }
.topbar .crumbs { font-size: .86rem; color: var(--ink-mute); }
.topbar .crumbs a { color: inherit; text-decoration: none; }
.topbar .crumbs a:hover { color: var(--ink-soft); }
.topbar .crumbs b { color: var(--ink-soft); font-weight: 500; }

/* ── Mobile drawer chrome — hidden on desktop, revealed ≤900 ── */
.m-top { display: none; }
.m-burger { display: none; align-items: center; justify-content: center; width: 44px; height: 44px; flex: none; border-radius: var(--r-sm); background: rgba(255,255,255,.05); border: 1px solid var(--glass-border); color: var(--ink); cursor: pointer; padding: 0; transition: background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), transform var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.m-burger:hover { background: rgba(255,255,255,.09); }
.m-burger:active { transform: scale(.94); transition-duration: var(--dur-fast, .12s); }
.m-burger svg { width: 20px; height: 20px; }
/* Drawer header (brand · close) + nav section label — exist in the shared
   markup but render only inside the ≤900 drawer. The close button is a
   normal flex child of .drawer-head (NOT absolutely positioned), so it can
   never overlap or truncate the profile card. */
.drawer-head { display: none; }
.side-nav-label { display: none; }
.drawer-close { display: none; width: 44px; height: 44px; flex: none; align-items: center; justify-content: center; border-radius: 999px; background: rgba(255,255,255,.045); border: 1px solid var(--glass-border); color: var(--ink-soft); cursor: pointer; padding: 0; transition: color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), border-color var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)), background var(--dur-micro, .18s) var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
.drawer-close:hover { color: var(--ink); border-color: var(--glass-border-2); background: rgba(255,255,255,.09); }
.drawer-close svg { width: 17px; height: 17px; transition: transform var(--dur-base, .24s) var(--ease-spring, cubic-bezier(.34,1.4,.5,1)); }
/* The X answers the hover with a quarter turn — a small tactile confirm */
@media (hover: hover) and (pointer: fine) { .drawer-close:hover svg { transform: rotate(90deg); } }
.drawer-close:active { background: rgba(255,255,255,.12); }
/* Scrim: strong enough to isolate the drawer from page content (was .6 + 3px
   blur — too weak to read as a modal layer). */
.drawer-overlay { position: fixed; inset: 0; z-index: 55; background: rgba(8,7,6,.72); backdrop-filter: blur(8px) saturate(120%); -webkit-backdrop-filter: blur(8px) saturate(120%); opacity: 0; pointer-events: none; transition: opacity .28s var(--ease-swift, cubic-bezier(.4, 0, .2, 1)); }
body.drawer-open .drawer-overlay { opacity: 1; pointer-events: auto; }

/* Consistent keyboard focus ring across shell controls */
.side-nav a:focus-visible, .pw-upgrade-btn:focus-visible,
.m-burger:focus-visible, .drawer-close:focus-visible {
  outline: 2px solid rgba(232,168,94,.7); outline-offset: 2px;
}
/* Logout gets the matching red ring (same as the public drawer's logout) */
.pw-logout-btn:focus-visible { outline: 2px solid rgba(232,137,126,.6); outline-offset: 2px; }

@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; padding: 14px; }
  .m-top { display: flex; align-items: center; gap: 14px; padding: 10px 14px; margin: 14px 14px 4px; }
  .m-burger { display: inline-flex; }
  .m-top .brand { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .m-top .btn { flex: none; --pad-x: 13px; --pad-y: 9px; font-size: .82rem; }

  /* Sidebar reused as a slide-out drawer — same markup, no duplicate component.
     The drawer OWNS its surface: the desktop .glass card fill (~5-7% white) is
     far too translucent to sit over live page content, and glass.css strips
     backdrop-filter from .glass at ≤768 (iOS GPU budget) — which left the
     drawer an unblurred, near-transparent sheet on phones. Near-opaque
     liquid-glass surface per the canonical public .m-menu (rgba .97 + blur 28).
     Selector is aside.side (0,1,1) so it outranks both .glass rules (0,1,0)
     regardless of file order. */
  aside.side {
    display: flex; position: fixed; top: 0; left: 0; bottom: 0; height: 100%;
    width: 296px; max-width: 88vw; z-index: 60; border-radius: 0 20px 20px 0;
    transform: translateX(-100%); transition: transform .28s var(--ease-swift, cubic-bezier(.4, 0, .2, 1));
    overflow-y: auto; overscroll-behavior: contain;
    padding: max(14px, env(safe-area-inset-top)) 14px calc(16px + env(safe-area-inset-bottom));
    /* Near-opaque bg — 14px reads identically to the old 28px at a fraction
       of the GPU cost on this full-height, mobile-only drawer (§12 budget). */
    background: rgba(10,9,8,.97);
    backdrop-filter: blur(14px) saturate(150%);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    border: 0; border-right: 1px solid rgba(255,255,255,.09);
    box-shadow: none;
  }
  /* Suppress the .glass hairline-rim pseudo (the drawer draws its own edge)
     and paint ambient amber light wells instead — same language as .m-menu. */
  aside.side::before { content: none; }
  aside.side::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
    border-radius: inherit;
    background:
      radial-gradient(300px 240px at 92% -4%, rgba(232,168,94,.12), transparent 70%),
      radial-gradient(260px 220px at -14% 104%, rgba(232,168,94,.05), transparent 70%);
  }
  body.drawer-open .side { transform: translateX(0); box-shadow: 24px 0 80px rgba(0,0,0,.5), 0 32px 80px rgba(0,0,0,.55); }

  /* Drawer header: brand · close — a real layout row above the profile card */
  .drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-shrink: 0; padding: 2px 2px 13px; margin-bottom: 14px; border-bottom: 1px solid rgba(255,255,255,.07); }
  .drawer-head .brand { font-size: .98rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .drawer-close { display: inline-flex; }

  /* Section rhythm: the mono "Menu" eyebrow (canonical drawer language)
     replaces the bare hairline between profile and nav */
  .side .side-sep { display: none; }
  .side-nav-label { display: flex; align-items: center; gap: 10px; margin: 16px 4px 8px; font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace; font-size: 10px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-mute); }
  .side-nav-label::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, rgba(255,255,255,.10), transparent); }
  .side-nav { margin-top: 0; gap: 4px; }

  /* Comfortable touch targets + press feedback inside the drawer */
  .side-nav a { padding: 12px 13px; min-height: 48px; font-size: .95rem; border-radius: 12px; }
  .side-nav a svg { width: 18px; height: 18px; }
  .side-nav a:active { background: rgba(255,255,255,.07); }
  .pw-upgrade-btn { padding: 12px; min-height: 44px; }
  .pw-logout-btn { padding: 12px; min-height: 48px; margin-top: 8px; }

  /* Bottom block (credits + logout) separated from the nav with its own rule */
  .side-bottom { padding-top: 14px; border-top: 1px solid rgba(255,255,255,.07); }
}

/* Fallback when backdrop-filter is unsupported: fully opaque drawer */
@supports not (backdrop-filter: blur(1px)) {
  @media (max-width: 900px) { aside.side { background: rgba(10,9,8,.99); } }
}

/* Staggered content entrance — premium reveal, motion-safe (skipped entirely
   under prefers-reduced-motion; the base state stays fully visible there) */
@media (max-width: 900px) and (prefers-reduced-motion: no-preference) {
  .side > * { opacity: 0; transform: translateX(-10px); transition: opacity .16s ease, transform .16s ease; }
  body.drawer-open .side > * { opacity: 1; transform: none; transition: opacity .34s var(--ease-out, cubic-bezier(.22,1,.36,1)), transform .34s var(--ease-out, cubic-bezier(.22,1,.36,1)); }
  body.drawer-open .side > :nth-child(2) { transition-delay: 40ms; }
  body.drawer-open .side > :nth-child(4) { transition-delay: 70ms; }
  body.drawer-open .side > :nth-child(5) { transition-delay: 100ms; }
  body.drawer-open .side > :nth-child(6) { transition-delay: 130ms; }
}


/* ═══════════════════════════════════════════════════════════════════
   INPUT-MODALITY FOCUS SYSTEM — product-wide interaction contract.
   Focus rings are for keyboard users. iOS Safari matches :focus-visible
   on PROGRAMMATIC focus (drawer/modal focus traps + focus-restore), so
   tap-driven flows previously stranded rings (UA blue where uncustomized,
   amber where customized). dashboard-shell.js stamps
   <html data-input="pointer|kbd"> from the LAST input type; while it is
   "pointer", non-form focus outlines are suppressed. Form fields
   (input/textarea/select) ALWAYS keep their focus styles — they signal
   active text entry. Tab/arrow keys restore every ring instantly.
   Every ring in the product is outline-based (audited 2026-07-06), so
   suppressing outline alone is complete. Keep in sync with the copy in
   public-header.css. ═════════════════════════════════════════════════ */
html[data-input="pointer"] :focus:not(input):not(textarea):not(select) {
  outline: none !important;
}

/* Touch polish: kill the iOS gray tap-flash (components provide their own
   pressed states) and the double-tap-zoom delay on interactive elements. */
a, button, [role="button"], label, select, summary, [tabindex] {
  -webkit-tap-highlight-color: transparent;
}
a, button, input, select, textarea, label, summary {
  touch-action: manipulation;
}

/* ══════════════════════════════════════════════════════════════════════
   PREMIUM PREVIEW — ONE system for every locked Standard+ surface.
   Philosophy (§premium-demo): a locked page is an INTERACTIVE LABELED DEMO —
   the REAL product running its REAL client-side interactions on fictional
   data. Never an upgrade card, never a frozen screenshot, and never ambient
   data a user could mistake for their own. Two halves:
   · INTERACTIVE: everything the product does client-side works on the demo
     data (filter/search/sort/paginate/stage-change on Applications; digest
     jumps + copy-rewrite buttons on ATS). Local demo writes confirm with an
     honest "nothing is saved" toast. The demo only exposes interactions the
     real product has — invented demo-only UI would itself deceive.
   · LABELED: three honesty layers on every surface —
     1. .pv-ribbon — orientation first: "an interactive demo, not your data"
        + the upgrade CTAs, ABOVE the demo.
     2. .pv-frame — the demo sits inside a visible amber-tinted boundary,
        so the fiction has an explicit beginning and end.
     3. .pv-strip — a slim sticky pill pinned inside the frame that stays in
        view for the demo's whole scroll depth (the ribbon scrolls away;
        this never does).
   Actions that need the USER'S OWN data (open/download documents, run a new
   analysis, optimize, export) are intercepted at the moment of intent and
   answered by the shared BHDemo.moment() sheet (assets/js/premium-demo.js) —
   a contextual, dismissible doorway to billing, never a wall.
   Shared here (loaded by all /dashboard/* routes) so Applications, ATS
   Analyzer, Billing, and Home all read identically.
   ══════════════════════════════════════════════════════════════════════ */

/* The demo frame: an amber-washed boundary around the demo region. Inside
   the frame = a live, fictional example; outside = the user's real account
   chrome. Internal spacing mirrors the pages' stack rhythm. */
.pv-frame {
  position: relative; border-radius: 24px; padding: 14px;
  border: 1px solid rgba(232,168,94,.24);
  background: linear-gradient(180deg, rgba(232,168,94,.05), rgba(232,168,94,.012) 220px);
  box-shadow: inset 0 1px 0 rgba(232,168,94,.1);
}
.pv-frame > * + * { margin-top: 16px; }

/* The environment banner: sticky, so no scroll position of the demo exists
   without an "interactive demo" label on screen. Sticky (not fixed) — it
   lives in the frame and leaves with it. z-index below the drawer band. */
.pv-strip {
  position: sticky; top: 10px; z-index: 45;
  display: flex; align-items: center; justify-content: center; gap: 5px 13px; flex-wrap: wrap;
  width: max-content; max-width: 100%; margin: 0 auto;
  padding: 8px 16px; border-radius: 99px;
  background: rgba(26,19,11,.92);
  border: 1px solid rgba(232,168,94,.4);
  backdrop-filter: blur(12px) saturate(130%); -webkit-backdrop-filter: blur(12px) saturate(130%);
  box-shadow: 0 12px 30px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.08);
  font-family: 'JetBrains Mono', monospace; font-size: .6rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--amber-bright);
}
.pv-strip::before {
  content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%;
  background: var(--amber-bright); box-shadow: 0 0 10px rgba(232,168,94,.8);
}
.pv-strip-txt { white-space: nowrap; }
.pv-strip-link {
  color: var(--ink); text-decoration: none; white-space: nowrap; font: inherit;
  border-bottom: 1px solid rgba(255,255,255,.28); padding-bottom: 1px;
}
.pv-strip-link:hover { color: #fff; border-bottom-color: rgba(255,255,255,.55); }
.pv-strip-link:focus-visible { outline: 2px solid rgba(232,168,94,.7); outline-offset: 3px; border-radius: 2px; }

/* Slim supporting ribbon — a bar, never a card. Amber-tinted, one line of
   context + a primary upgrade + a quiet plans link. */
.pv-ribbon {
  display: flex; align-items: center; justify-content: space-between; gap: 16px 24px;
  flex-wrap: wrap; padding: 15px 20px; border-radius: 16px;
  background: linear-gradient(100deg, rgba(232,168,94,.13), rgba(232,168,94,.05) 58%, rgba(255,255,255,.02));
  border: 1px solid rgba(232,168,94,.3);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09), 0 12px 30px rgba(0,0,0,.26);
}
.pv-ribbon-lead { display: flex; align-items: center; gap: 14px; min-width: 0; }
.pv-lock {
  width: 40px; height: 40px; flex: none; border-radius: 11px; display: grid; place-items: center;
  background: rgba(232,168,94,.15); border: 1px solid rgba(232,168,94,.32); color: var(--amber);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);
}
.pv-lock svg { width: 19px; height: 19px; }
.pv-ribbon-txt { min-width: 0; }
.pv-ribbon-txt b { display: block; font-size: .95rem; font-weight: 700; color: var(--ink); letter-spacing: -.01em; }
/* Direct child only — the copy inside is bilingual .t-en/.t-de span pairs, and
   a bare descendant selector would force BOTH languages visible (§12 family). */
.pv-ribbon-txt > span { display: block; font-size: .85rem; color: var(--ink-soft); line-height: 1.45; margin-top: 2px; }
.pv-ribbon-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pv-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 42px; padding: 11px 18px; border-radius: 11px;
  font: 600 .88rem/1 'Schibsted Grotesk', system-ui, sans-serif; cursor: pointer;
  text-decoration: none; white-space: nowrap;
  border: 1px solid var(--glass-border-2); background: rgba(255,255,255,.05); color: var(--ink);
  transition: background .18s, border-color .18s, transform .18s, box-shadow .18s;
}
.pv-btn svg { width: 16px; height: 16px; flex: none; }
.pv-btn:where(:hover) { background: rgba(255,255,255,.09); border-color: rgba(255,255,255,.22); transform: translateY(-1px); } /* §btn-variant-hover */
.pv-btn:active { transform: translateY(0) scale(.985); }
.pv-btn:focus-visible { outline: 2px solid rgba(232,168,94,.7); outline-offset: 2px; }
.pv-btn--primary {
  background: linear-gradient(180deg, var(--amber-bright), var(--amber-deep));
  border-color: rgba(255,255,255,.18); color: var(--amber-ink);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 0 26px rgba(232,168,94,.14);
}
.pv-btn--primary:hover { background: linear-gradient(180deg, #f5c882, var(--amber-bright)); box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 0 30px rgba(232,168,94,.22); } /* §btn-variant-hover */

/* Small "Sample" tag — dropped onto the sample's first panel so the preview
   never reads as the user's own data. */
.pv-tag {
  display: inline-flex; align-items: center; gap: 6px; font-family: 'JetBrains Mono', monospace;
  font-size: .58rem; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-mute);
  padding: 4px 10px; border-radius: 99px; border: 1px solid var(--glass-border); background: rgba(255,255,255,.03);
}
.pv-tag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--amber-bright); opacity: .7; }

@media (max-width: 640px) {
  .pv-ribbon { padding: 14px 16px; }
  /* Multi-line ribbon copy on phones: keep the lock icon anchored to the TOP
     (title line) instead of floating mid-paragraph (§ats-qa V2). */
  .pv-ribbon-lead { align-items: flex-start; }
  .pv-ribbon-actions { width: 100%; }
  .pv-ribbon-actions .pv-btn { flex: 1; }
  .pv-frame { padding: 8px; border-radius: 20px; }
  .pv-strip { top: 8px; padding: 7px 13px; font-size: .56rem; }
}
@media (prefers-reduced-motion: reduce) {
  .pv-btn, .pv-btn:active { transition: none; transform: none; }
}

/* §brand-mark (2026-07-18): SVG dovetail mark inside the amber tile + two-tone wordmark */
.brand-mark svg { width: 58%; height: auto; display: block; }
.brand .brand-held { color: #e8a85e; }
