/* ==========================================================================
   Components — buttons, cards, fields, chips, modal, toast, progress
   ========================================================================== */

/* ------------------------------------------------------------- Button --- */
.btn {
  --btn-bg: var(--surface); --btn-fg: var(--ink); --btn-bd: var(--line-strong);
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 42px; padding: 0 var(--s-4);
  border-radius: var(--r-sm);
  background: var(--btn-bg); color: var(--btn-fg);
  box-shadow: inset 0 0 0 1px var(--btn-bd);
  font-family: var(--font-head); font-size: var(--t-base); font-weight: 500;
  white-space: nowrap;
  transition: transform var(--d-fast) var(--e-out),
              background-color var(--d-fast) var(--e-out),
              box-shadow var(--d-fast) var(--e-out),
              color var(--d-fast) var(--e-out);
}
.btn svg { width: 17px; height: 17px; flex: none; }
.btn:hover  { transform: translateY(-1px); box-shadow: inset 0 0 0 1px var(--line-strong), var(--sh-2); }
.btn:active { transform: translateY(0) scale(.985); transition-duration: 60ms; }
.btn[disabled] { opacity: .5; transform: none !important; box-shadow: inset 0 0 0 1px var(--line); }

.btn.primary {
  --btn-bg: var(--primary); --btn-fg: var(--on-primary); --btn-bd: transparent;
  box-shadow: var(--sh-2);
}
.btn.primary:hover { --btn-bg: var(--primary-hover); box-shadow: var(--sh-3); }
/* --accent-ink is the text-safe tone in BOTH themes: dark in light mode,
   light in dark mode. So the label must be --surface, not a literal white —
   white on the dark-theme value is 1.8:1. */
.btn.accent { --btn-bg: var(--accent-ink); --btn-fg: var(--surface); --btn-bd: transparent; box-shadow: var(--sh-2); }
.btn.ghost  { --btn-bg: transparent; --btn-bd: transparent; color: var(--ink-soft); }
.btn.ghost:hover { --btn-bg: var(--surface-3); color: var(--ink); box-shadow: none; }
.btn.danger { --btn-bg: var(--danger-wash); --btn-fg: var(--danger); --btn-bd: transparent; }
.btn.sm { min-height: 34px; padding: 0 var(--s-3); font-size: var(--t-sm); }
.btn.lg { min-height: 52px; padding: 0 var(--s-6); font-size: var(--t-md); font-weight: 600; }
.btn.block { width: 100%; }

/* Icon-only controls always carry an aria-label; 44px hit area via padding */
.icon-btn {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border-radius: var(--r-sm);
  color: var(--ink-soft);
  box-shadow: inset 0 0 0 1px transparent;
  transition: background-color var(--d-fast) var(--e-out),
              color var(--d-fast) var(--e-out),
              transform var(--d-fast) var(--e-out-expo);
}
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn:hover { background: var(--surface-3); color: var(--ink); }
.icon-btn:active { transform: scale(.9); }

/* Theme toggle — the icon rotates through rather than swapping instantly */
#themeToggle svg { transition: transform var(--d-slow) var(--e-out-expo), opacity var(--d-base) var(--e-out); }
#themeToggle.spin svg { transform: rotate(180deg) scale(.6); opacity: 0; }

/* ---------------------------------------------------------- Lang switch -- */
.lang-switch {
  position: relative; display: flex; gap: 2px; padding: 3px;
  background: var(--surface-3); border-radius: var(--r-pill);
}
.lang-switch button {
  position: relative; z-index: 1;
  /* Equal width so the thumb only ever translates. It used to animate its
     own width to match each label, which is a layout property and thrashes. */
  width: 38px; height: 30px; padding: 0;
  border-radius: var(--r-pill);
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .04em;
  color: var(--ink-soft);
  transition: color var(--d-base) var(--e-out);
}
.lang-switch button[aria-pressed="true"] { color: var(--on-primary); }
.lang-switch .lang-thumb {
  position: absolute; z-index: 0; top: 3px; bottom: 3px;
  border-radius: var(--r-pill); background: var(--primary);
  box-shadow: var(--sh-1);
  transition: transform var(--d-base) var(--e-out-expo);
}

/* --------------------------------------------------------------- Card --- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  transition: background-color var(--d-base) var(--e-inout),
              border-color var(--d-base) var(--e-inout),
              box-shadow var(--d-base) var(--e-out),
              transform var(--d-base) var(--e-out);
}
.card.pad { padding: var(--s-5); }
.card.lift:hover { box-shadow: var(--sh-3); transform: translateY(-2px); }

.panel-head { display: flex; align-items: flex-start; gap: var(--s-4); margin-bottom: var(--s-5); }
.panel-head > div { min-width: 0; }
.panel-head p { color: var(--ink-soft); margin-top: var(--s-2); max-width: 62ch; }

.eyebrow {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-head);
  font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint);
}
.eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }

/* --------------------------------------------------------- Step badge --- */
.step-badge {
  flex: none; display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-pill);
  background: var(--lv-wash, var(--surface-3));
  color: var(--lv-ink, var(--ink-soft));
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.step-badge b {
  display: grid; place-items: center;
  width: 20px; height: 20px; border-radius: 50%;
  /* See views.css: text on a level colour uses -ink over --surface. */
  background: var(--lv-ink, var(--accent-ink)); color: var(--surface);
  font-size: var(--t-xs); font-variant-numeric: tabular-nums;
  /* <b> defaults to `bolder`, which against this 700 parent resolves to 900 —
     a weight neither family loads, so the browser was synthesising it. */
  font-weight: 700;
}

/* -------------------------------------------------------------- Chip ---- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px var(--s-3); min-height: 26px;
  border-radius: var(--r-pill);
  background: var(--surface-3); color: var(--ink-soft);
  font-size: var(--t-xs); font-weight: 600;
  white-space: nowrap;            /* a chip label must never wrap */
}
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.chip.impact   { background: var(--lv-impact-wash);   color: var(--lv-impact-ink); }
.chip.outcome  { background: var(--lv-outcome-wash);  color: var(--lv-outcome-ink); }
.chip.output   { background: var(--lv-output-wash);   color: var(--lv-output-ink); }
.chip.activity { background: var(--lv-activity-wash); color: var(--lv-activity-ink); }
.chip.assume   { background: var(--lv-assume-wash);   color: var(--lv-assume-ink); }

/* ------------------------------------------------------------- Fields --- */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }
.field { display: grid; gap: var(--s-2); min-width: 0; }
.field.full { grid-column: 1 / -1; }
@media (max-width: 720px) { .form-grid { grid-template-columns: minmax(0, 1fr); } }

.field > label {
  font-family: var(--font-head); font-size: var(--t-sm); font-weight: 600;
  display: flex; align-items: baseline; gap: var(--s-2);
}
.field > label .opt {
  font-family: var(--font-body); font-weight: 400;
  font-size: var(--t-xs); color: var(--ink-faint);
}
.field .help { font-size: var(--t-xs); color: var(--ink-soft); }

input[type="text"], textarea {
  width: 100%;
  padding: var(--s-3) var(--s-4);
  min-height: 46px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--ink);
  transition: border-color var(--d-fast) var(--e-out),
              background-color var(--d-fast) var(--e-out),
              box-shadow var(--d-fast) var(--e-out);
}
textarea {
  min-height: 108px; resize: vertical; line-height: var(--lh-body);
  /* The problem statement ran to 80 characters a line while being typed. */
  max-width: var(--measure);
}
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
input:hover, textarea:hover { border-color: var(--line-strong); }
input:focus, textarea:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-wash);
}

/* Counter under long-form inputs */
.field-foot { display: flex; justify-content: space-between; gap: var(--s-3); font-size: var(--t-xs); color: var(--ink-faint); }
.field-foot .count { font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- Note ---- */
.note {
  display: flex; gap: var(--s-3);
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--accent-wash);
  color: var(--ink);
  font-size: var(--t-sm); line-height: 1.55;
}
.note svg { width: 18px; height: 18px; flex: none; color: var(--accent-ink); margin-top: 1px; }
/* Uncapped, these callouts reached 132 characters a line — nearly twice a
   comfortable measure. The icon is a flex sibling, so the cap goes on the text. */
.note > span { max-width: var(--measure); }
.note b { font-family: var(--font-head); }
.note.warn { background: var(--lv-assume-wash); }
.note.warn svg { color: var(--lv-assume-ink); }
.note.good { background: var(--success-wash); }
.note.good svg { color: var(--success); }

/* ---------------------------------------------------------- Progress ---- */
.progress-ring { display: grid; place-items: center; position: relative; }
.progress-ring svg { transform: rotate(-90deg); overflow: visible; }
.progress-ring circle { fill: none; stroke-linecap: round; }
.progress-ring .track { stroke: var(--surface-3); }
.progress-ring .value {
  stroke: url(#ringGrad);
  transition: stroke-dashoffset var(--d-slower) var(--e-out);
}
/* Angka dan tanda persen adalah SATU bacaan, jadi harus satu baris.
   Sebelumnya ini grid dengan dua anak dan aliran baris bawaan, sehingga "0"
   dan "%" tersusun bertumpuk di dalam cincin 62px. */
/* Two nested boxes on purpose:
   .pct centres the group in the ring, .pct-inner keeps the digits and the
   per-cent sign on a shared baseline. Doing both on one element does not
   work — `align-items: baseline` in a full-height box aligns the group to
   the TOP of that box, which pushed the number out of the ring. */
.progress-ring .pct {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--font-head); font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1;
  /* Sized so the widest value ("100%") clears the ring's inner diameter:
     the 52px ring less its 5px stroke leaves ~39px, and "100%" measures ~34px.
     It lives here, not on .pct-inner, because the review panel renders the
     percentage straight into .pct with no inner wrapper. */
  font-size: var(--t-sm);
}
.progress-ring .pct-inner {
  display: flex; align-items: baseline; gap: 1px; max-width: 100%;
}
/* The review panel's ring is 66px (inner ~45px), so it can carry the larger
   size without touching the sides. */
.progress-ring.lg .pct { font-size: var(--t-md); }
/* Tanda persen lebih kecil supaya angkanya yang dibaca lebih dulu, dan supaya
   "100%" tetap muat di dalam cincin. */
.progress-ring .pct #ringSuffix { font-size: .72em; font-weight: 600; opacity: .75; }

.bar { height: 8px; border-radius: var(--r-pill); background: var(--surface-3); overflow: hidden; }
.bar > i {
  display: block; height: 100%; width: 100%; border-radius: inherit;
  background: linear-gradient(90deg, var(--brand-teal), var(--brand-lime));
  /* Scale, not width: the fill is a transform so it composites instead of
     forcing layout on every frame. Origin left so it grows from the start. */
  transform-origin: left center;
  transform: scaleX(var(--fill, 0));
  transition: transform var(--d-slower) var(--e-out);
}

/* ------------------------------------------------------------- Modal ---- */
.modal-layer {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center;
  padding: var(--s-4);
  background: color-mix(in srgb, var(--brand-navy-deep) 55%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; visibility: hidden;
  transition: opacity var(--d-base) var(--e-out), visibility var(--d-base);
}
.modal-layer.open { opacity: 1; visibility: visible; }
.modal {
  width: min(560px, 100%);
  padding: var(--s-5);
  background: var(--surface);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-4);
  transform: translateY(14px) scale(.97);
  opacity: 0;
  transition: transform var(--d-base) var(--e-out-expo), opacity var(--d-base) var(--e-out);
  max-height: calc(100svh - var(--s-7));
  overflow-y: auto;
}
.modal-layer.open .modal { transform: none; opacity: 1; }
.modal-head { display: flex; align-items: flex-start; gap: var(--s-3); margin-bottom: var(--s-4); }
.modal-head h3 { font-size: var(--t-lg); }
.modal-head .icon-btn { margin-left: auto; margin-top: -4px; }
.modal-foot { display: flex; justify-content: flex-end; gap: var(--s-3); margin-top: var(--s-5); }

/* ------------------------------------------------------------- Toast ---- */
.toast {
  position: fixed; z-index: 140;
  left: 50%; bottom: calc(var(--s-5) + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: var(--s-3);
  max-width: min(440px, calc(100vw - var(--s-6)));
  padding: var(--s-3) var(--s-3) var(--s-3) var(--s-4);
  background: var(--brand-navy-deep); color: #fff;
  border-radius: var(--r-pill);
  box-shadow: var(--sh-4);
  font-size: var(--t-sm);
  transform: translate(-50%, 140%);
  opacity: 0;
  transition: transform var(--d-slow) var(--e-out-expo), opacity var(--d-base) var(--e-out);
}
.toast.show { transform: translate(-50%, 0); opacity: 1; }
.toast svg { width: 17px; height: 17px; flex: none; }
.toast .icon-btn { color: rgba(255,255,255,.72); width: 32px; height: 32px; }
.toast .icon-btn:hover { background: rgba(255,255,255,.14); color: #fff; }
@media (max-width: 1024px) { .toast { bottom: calc(80px + env(safe-area-inset-bottom)); } }

/* --------------------------------------------------------- Empty state -- */
.empty {
  display: grid; justify-items: center; gap: var(--s-3);
  padding: var(--s-7) var(--s-5);
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-md);
  text-align: center; color: var(--ink-soft);
}
.empty svg { width: 34px; height: 34px; color: var(--ink-faint); }
.empty b { font-family: var(--font-head); color: var(--ink); display: block; }

/* --------------------------------------------------------- Save status -- */
.save-status {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-xs); color: var(--ink-soft); white-space: nowrap;
}
.save-status .pip {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--success); flex: none;
  transition: background-color var(--d-base) var(--e-out);
}
.save-status[data-state="saving"] .pip { background: var(--lv-activity-solid); animation: pulse 1s var(--e-inout) infinite; }
@keyframes pulse { 50% { opacity: .3; transform: scale(.7); } }

/* ==========================================================================
   Topbar action set — three tiers, because eight controls never fit a phone:
     wide    : labelled buttons
     medium  : icon-only buttons
     narrow  : file actions collapse into one overflow menu
   ========================================================================== */
.action-menu { position: relative; }
.topbar-sep { width: 1px; height: 24px; background: var(--line); margin: 0 var(--s-1); flex: none; }
.menu-caret { transform: rotate(90deg); opacity: .55; }
/* Rows that only make sense in the bottom-sheet form of this menu. */
.only-mobile { display: contents; }
@media (min-width: 1025px) { .only-mobile { display: none; } }
@media (max-width: 1024px) { .desk-only { display: none; } }

/* The file actions are one menu at every width now, so the old three-tier
   collapse is gone with them. Only the mobile anchoring rule remains. */
@media (max-width: 820px) {
  .action-menu { position: static; }
  #menuBtn .btn-label, #menuBtn .menu-caret { display: none; }
  #menuBtn { padding: 0 var(--s-3); }
}

.menu-pop {
  position: absolute; z-index: 90;
  top: calc(100% + var(--s-2)); right: 0;
  min-width: 232px; padding: var(--s-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-3);
  display: grid; gap: 2px;
  transform-origin: top right;
  opacity: 0; visibility: hidden; transform: scale(.94) translateY(-6px);
  transition: opacity var(--d-fast) var(--e-out),
              transform var(--d-base) var(--e-out-expo),
              visibility var(--d-base);
}
.menu-pop.open { opacity: 1; visibility: visible; transform: none; }
.menu-pop button {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%; min-height: 44px; padding: 0 var(--s-3);
  border-radius: var(--r-sm);
  color: var(--ink); font-size: var(--t-base); text-align: left;
  transition: background-color var(--d-fast) var(--e-out);
}
.menu-pop button svg { width: 17px; height: 17px; color: var(--ink-soft); flex: none; }
.menu-pop button:hover { background: var(--surface-3); }

/* The breadcrumb must yield space before the actions do. */
.crumb { flex: 1 1 auto; }
.topbar-actions { flex: 0 0 auto; }
@media (max-width: 820px) {
  .crumb-name { max-width: none; }
  .crumb-root, .crumb > [data-icon] { display: none; }
}

/* Anchored to its button, the menu panel's left edge falls off a 375px screen.
   Pin it to the viewport instead so it is always fully on-screen.
   This must sit after the base .menu-pop rule to win on source order. */
@media (max-width: 820px) {
  .menu-pop {
    position: fixed; left: auto; right: var(--s-3);
    top: calc(var(--topbar) + var(--s-2));
    max-width: calc(100vw - var(--s-5));
    /* Eleven items on a short phone ran past the bottom of the screen with
       no way to reach the last of them. */
    max-height: calc(100svh - var(--topbar) - var(--s-6));
    overflow-y: auto; overscroll-behavior: contain;
  }
  /* Opened from the bottom tab bar, the panel belongs at the bottom. setMenu()
     has always tagged which end the tap came from and even preserved the tag
     across a re-render -- the rule that answers it was never written, so a
     thumb on the last tab opened a panel 145px above it, at the far end of the
     phone, growing away from the finger. Rise from the tab instead. */
  /* .topbar carries a backdrop-filter, and that makes it the containing block
     for every fixed-position descendant -- so this panel's "fixed" offsets are
     measured from a 64px bar, not from the viewport. The top-anchored rule
     above is only correct by luck: the bar's own top edge is pinned to y=0. A
     bottom offset gets no such luck. It resolved against the bar's BOTTOM and
     put the panel 549px above the top of the screen. So anchor this one by top
     as well, and pull it up by its own height -- which needs no height known
     in advance, and no assumption beyond the one the rule above already makes. */
  .menu-pop.from-bottom {
    top: calc(100svh - var(--mobile-nav-h) - env(safe-area-inset-bottom) - var(--s-2));
    bottom: auto;
    max-height: calc(100svh - var(--topbar) - var(--mobile-nav-h) - var(--s-5));
    transform-origin: bottom right;
    transform: translateY(calc(-100% + 6px)) scale(.94);
  }
  .menu-pop.from-bottom.open { transform: translateY(-100%); }
}

/* ==========================================================================
   Account, plans, payment and paywall
   ========================================================================== */
.modal.wide { width: min(720px, 100%); }

.btn.danger-solid { --btn-bg: var(--danger); --btn-fg: var(--surface); --btn-bd: transparent; box-shadow: var(--sh-2); }
.btn.accent .btn-label { display: inline; }
/* The breadcrumb must be allowed to shrink, but never to nothing. */
.crumb { min-width: 8ch; }

.acct-chip { padding: 0 var(--s-2); min-height: 34px; box-shadow: none; background: transparent; }
.acct-chip:hover { box-shadow: none; background: var(--surface-3); }
.acct-chip .chip { pointer-events: none; }

/* ---- auth --------------------------------------------------------------- */
input[type="email"], input[type="password"] {
  width: 100%; padding: var(--s-3) var(--s-4); min-height: 46px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); color: var(--ink);
  transition: border-color var(--d-fast) var(--e-out), box-shadow var(--d-fast) var(--e-out);
}
input[type="email"]:focus, input[type="password"]:focus {
  outline: none; background: var(--surface);
  border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-wash);
}

.auth-err {
  margin-top: var(--s-4); padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  background: var(--danger-wash); color: var(--danger);
  font-size: var(--t-sm); font-weight: 600;
}
.auth-note {
  display: flex; gap: var(--s-3); margin-top: var(--s-5);
  padding-top: var(--s-4); border-top: 1px solid var(--line);
  font-size: var(--t-xs); color: var(--ink-soft); line-height: 1.55;
}
.auth-note svg { width: 15px; height: 15px; flex: none; margin-top: 1px; }

.plan-table-wrap { overflow-x: auto; }
.plan-table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.plan-table th, .plan-table td { padding: var(--s-3) var(--s-3); text-align: left; }
.plan-table thead th {
  font-family: var(--font-head); font-size: var(--t-xs);
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft);
  border-bottom: 2px solid var(--line-strong);
}
.plan-table tbody th { font-weight: 400; color: var(--ink); }
.plan-table tbody tr { border-bottom: 1px solid var(--line); }
.plan-table td { color: var(--ink-soft); white-space: nowrap; }
.plan-table .pro { color: var(--accent-ink); font-weight: 600; }
.plan-table tbody tr:hover { background: var(--surface-2); }

@media (max-width: 560px) {
  .plan-head { grid-template-columns: 1fr; }
  .modal.wide { width: 100%; }
}

/* The topbar language switch folds into the overflow menu on phones, where
   the programme name needs the space more than a rarely-used setting. */
.menu-sep { border: 0; border-top: 1px solid var(--line); margin: var(--s-2) 0; }
.menu-tick { margin-left: auto; display: grid; place-items: center; color: var(--accent-ink); }
.menu-tick svg { width: 15px; height: 15px; }
.menu-pop [data-act="lang"][aria-checked="true"] { color: var(--accent-ink); font-weight: 600; }

@media (max-width: 820px) {
  .lang-switch { display: none; }
  .btn.accent .btn-label { display: inline; }
/* The breadcrumb must be allowed to shrink, but never to nothing. */
.crumb { min-width: 8ch; }
}

/* ---- Outcome negatif ------------------------------------------------------
   Prinsip kedua SROI mewajibkan outcome yang merugikan ikut dicatat. Ditandai
   dengan warna peringatan, bukan warna galat: ini bukan kesalahan pengisian,
   melainkan kejujuran. */
.neg-tag{
  display:inline-block; margin-left:8px; padding:1px 7px; border-radius:999px;
  font-size: var(--t-xs); font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  /* --lv-assume-tint was never defined, so this always fell through to the
     hardcoded hex and stayed light-theme pink in dark mode. */
  background: var(--lv-assume-wash); color: var(--lv-assume-ink);
}
.icon-btn.neg-on{ color:var(--lv-assume-solid,#c0392b) }

/* Pemisah "atau" antara Google dan formulir email. Garisnya digambar dengan
   pseudo-element supaya tidak butuh markup tambahan. */
.auth-sep{ display:flex; align-items:center; gap:10px; margin:0 0 14px; }
.auth-sep::before,.auth-sep::after{ content:""; flex:1; height:1px; background:var(--line, #e5e9ef); }
.auth-sep span{ font-size:.75rem; color:var(--ink-soft); text-transform:lowercase; }
.btn.block{ width:100%; justify-content:center; }

/* ==========================================================================
   Rail progress card — a 62px ring left the copy beside it about 150px in a
   264px rail, so every line wrapped. Smaller ring, tighter type, no inline
   styles.
   ========================================================================== */
.progress-card {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
}
.progress-card .progress-ring { width: 52px; height: 52px; flex: none; }
.progress-copy { min-width: 0; display: grid; gap: 1px; }
.progress-copy b {
  font-family: var(--font-head); font-size: var(--t-sm);
  font-weight: 600; line-height: 1.25;
  text-wrap: balance;
}
.progress-copy span {
  font-size: var(--t-xs); color: var(--ink-soft); line-height: 1.35;
}
/* Percentages are read as one token, so keep them on one line even at 100%. */
.progress-ring .pct { white-space: nowrap; }

/* Destructive rows in the file menu read as destructive before they are clicked. */
.menu-pop .menu-danger { color: var(--danger); }
.menu-pop .menu-danger svg { color: var(--danger); }
.menu-pop .menu-danger:hover { background: var(--danger-wash); }

/* The primary heading of each view is an h2 sitting under the page's sr-only
   h1, but it is not a bigger thing than it was as an h3 — the level changed to
   fix the outline, not the visual hierarchy. */
.view-title { font-size: var(--t-xl); }
.panel-subtitle { font-size: var(--t-lg); margin-bottom: var(--s-4); }

/* Real headings for the review's result sections. These were tracked-out
   all-caps divs: a label costume on text that is structurally a heading, and
   nothing a screen reader could use to move between the three result blocks. */
.section-label {
  font-family: var(--font-head); font-size: var(--t-base); font-weight: 600;
  color: var(--ink); margin-bottom: var(--s-3);
}
.section-label.spaced { margin-top: var(--s-6); }

/* ==========================================================================
   Narrow-screen stacking
   A heading beside its action button cannot fit a 375px phone: the text
   shrinks but the button will not, so the card was pushed 22px past the
   screen edge. Below 600px they stack instead. flex-wrap alone does not do
   it — a shrinkable text block always leaves "room", so the row never wraps
   and overflows instead.
   ========================================================================== */
@media (max-width: 600px) {
  .panel-head { flex-direction: column; align-items: stretch; }
  .panel-head .btn { align-self: flex-start; }

  /* Same shape of problem: a dot, a title, and two buttons on one line left
     the version name about 70px to wrap into. Actions move under it. */
  .version { flex-wrap: wrap; }
  .version .version-body { flex: 1 1 100%; order: 1; }
  .version .v-dot { order: 0; }
  .version .btn, .version .icon-btn { order: 2; }
}
