/* ═══════════════════════════════════════════════════════════════════════════
   V4 builder - layered on top of V3's style.css, reusing its tokens so the
   builder is unmistakably the same product as the checker.
   ═══════════════════════════════════════════════════════════════════════════ */

/* the builder is a two-pane workbench, not one of V3's centred "acts" */
body:has(.bshell) { overflow: hidden; }
.bshell {
  position: fixed; inset: calc(var(--hud-h) + env(safe-area-inset-top)) 0 0 0; z-index: 10;
  display: grid;
  /* the middle column is the drag handle; its own width never changes.
     --preview-w is read from localStorage by build.js and only takes effect
     on the desktop breakpoint below, where the divider is actually shown. */
  grid-template-columns: minmax(380px, 1fr) minmax(360px, 460px);
}
@media (min-width: 1081px) {
  .bshell { grid-template-columns: minmax(380px, 1fr) 14px clamp(320px, var(--preview-w, 460px), min(66vw, 900px)); }
}

/* ── the resize handle ──────────────────────────────────────────────────────
   Desktop only - on tablet/phone the panes stack, and there's nothing to
   drag between two things sitting on top of each other. */
.bdivider { display: none; }
@media (min-width: 1081px) {
  .bdivider {
    display: block; position: relative; cursor: col-resize; touch-action: none;
    -webkit-user-select: none; user-select: none;
  }
  .bdivider::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px;
    background: var(--edge); transform: translateX(-50%);
    transition: background .18s var(--ease), width .18s var(--ease);
  }
  .bdiv-grip {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 4px; height: 40px; border-radius: 3px; background: var(--edge);
    opacity: 0; transition: opacity .2s var(--ease), background .2s var(--ease), height .2s var(--ease);
  }
  .bdivider:hover::after,
  .bdivider.dragging::after,
  .bdivider:focus-visible::after { background: var(--ember); width: 2px; }
  .bdivider:hover .bdiv-grip,
  .bdivider.dragging .bdiv-grip,
  .bdivider:focus-visible .bdiv-grip { opacity: 1; background: var(--ember); height: 52px; }
  .bdivider:focus-visible { outline: none; }
  /* while actively dragging, kill transitions on the panes themselves so the
     resize tracks the pointer 1:1 instead of chasing it on a spring delay */
  .bshell.resizing .bform,
  .bshell.resizing .bside { transition: none !important; }
  .bshell.resizing { cursor: col-resize; }
  .bshell.resizing * { -webkit-user-select: none; user-select: none; }
}

/* ── left: the form ──────────────────────────────────────────────────────── */
.bform {
  overflow-y: auto; padding: clamp(22px, 3vw, 40px) clamp(16px, 3vw, 40px) 90px;
  display: grid; gap: 30px; align-content: start;
}
.bhead h1 {
  font-family: var(--f-d); font-weight: 700; font-size: clamp(26px, 3.4vw, 42px);
  letter-spacing: -.04em; line-height: 1.03; margin-bottom: 12px;
}
.bhead h1 em { font-family: var(--f-s); font-style: italic; font-weight: 400; color: var(--ember); }
.bhead p { font-size: 14px; line-height: 1.65; color: var(--dim); max-width: 62ch; }
.bhead b { color: var(--ink-2); font-weight: 600; }

.bsec { display: grid; gap: 12px; }
.bsec-h { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bnum {
  font-family: var(--f-m); font-size: 9.5px; letter-spacing: .14em; color: var(--ember);
  padding: 4px 7px; border-radius: 6px; box-shadow: inset 0 0 0 1px var(--edge);
}
.bsec-h h2 { font-family: var(--f-d); font-size: 18px; font-weight: 600; letter-spacing: -.028em; }
.btag {
  font-family: var(--f-m); font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 999px; color: var(--dim); box-shadow: inset 0 0 0 1px var(--edge);
}
.btag[data-tone="ok"] { color: var(--signal); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--signal) 40%, transparent); }
.btag[data-tone="warn"] { color: var(--gold); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold) 40%, transparent); }
.btag.soft { opacity: .7; }
.bsec-sub { font-size: 12.5px; line-height: 1.6; color: var(--dim); max-width: 64ch; }

/* ── target cards ────────────────────────────────────────────────────────── */
.tgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 9px; }
.tcard {
  text-align: left; padding: 14px 15px; border-radius: 13px; border: 0; cursor: pointer;
  background: var(--glass); box-shadow: inset 0 0 0 1px var(--edge); color: var(--ink);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease);
}
.tcard:hover { transform: translateY(-2px); }
.tcard.on { box-shadow: inset 0 0 0 1.5px var(--ember); background: color-mix(in srgb, var(--ember) 9%, transparent); }
.tcard b { display: block; font-size: 13.5px; font-weight: 600; letter-spacing: -.015em; }
.tcard small { display: block; font-size: 11.5px; color: var(--dim); margin-top: 4px; line-height: 1.45; }

/* ── fields ──────────────────────────────────────────────────────────────── */
.frow { display: grid; gap: 10px; }
.frow.two { grid-template-columns: 1fr 1fr; }
.frow.three { grid-template-columns: 1.4fr .8fr .8fr; }
.fld { display: grid; gap: 5px; }
.fld > span {
  font-family: var(--f-m); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim);
}
.fld > span i { font-style: normal; opacity: .6; text-transform: none; letter-spacing: 0; }
.fld input, .fld select, .fld textarea {
  width: 100%; font-family: var(--f-b); font-size: 13.5px; color: var(--ink);
  /* A form is the whole job on this page, so the inputs have to read as
     inputs at a glance. --edge alone is a hairline that all but disappears
     over the shader field; this lifts the fill away from the panel and gives
     the border enough contrast to define the box without turning the column
     into a stack of hard rectangles. */
  background: color-mix(in srgb, var(--glass) 100%, var(--ink) 6%);
  border: 0; border-radius: 10px; padding: 11px 12px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--edge) 100%, var(--ink) 22%),
              0 1px 2px rgba(0,0,0,.16);
  transition: box-shadow .16s var(--ease), background .16s var(--ease);
}
.fld input:hover, .fld select:hover, .fld textarea:hover {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--edge) 100%, var(--ink) 38%),
              0 1px 2px rgba(0,0,0,.16);
}
.fld textarea { line-height: 1.55; resize: vertical; }
.fld input:focus, .fld select:focus, .fld textarea:focus {
  outline: none;
  background: color-mix(in srgb, var(--glass) 100%, var(--ink) 9%);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--ember) 70%, transparent),
              0 0 0 3px color-mix(in srgb, var(--ember) 14%, transparent);
}
.fld select { appearance: none; cursor: pointer; }

/* ── the advice lines - the actual product ───────────────────────────────── */
.advice {
  font-size: 12.5px; line-height: 1.6; padding: 10px 13px; border-radius: 10px;
  color: var(--dim); background: var(--glass); box-shadow: inset 0 0 0 1px var(--edge);
  border-left: 2px solid var(--edge);
}
.advice b { color: var(--ink-2); }
.advice[data-tone="ok"]   { border-left-color: var(--signal); color: var(--ink-2); }
.advice[data-tone="warn"] { border-left-color: var(--gold); color: var(--ink-2); }
.advice[data-tone="bad"]  { border-left-color: var(--ember); color: var(--ink-2); }
.advice[data-tone="muted"]{ border-left-color: var(--dim); }
.advice[data-tone="info"] { border-left-color: var(--ember); color: var(--ink-2); }
.advice:empty, .advice[hidden] { display: none; }

.edu-block {
  display: grid; gap: 10px; padding: 14px; border-radius: 13px;
  box-shadow: inset 0 0 0 1px var(--edge);
}

/* ── repeatable blocks ───────────────────────────────────────────────────── */
.rep {
  display: grid; gap: 10px; padding: 14px; border-radius: 13px;
  box-shadow: inset 0 0 0 1px var(--edge); margin-bottom: 9px;
}
.rep-h { display: flex; align-items: center; justify-content: space-between; }
.rep-h span {
  font-family: var(--f-m); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim);
}
.rep-x {
  border: 0; background: none; cursor: pointer; color: var(--dim); font-size: 12px;
  width: 28px; height: 28px; border-radius: 8px;
}
.rep-x:hover { color: var(--ember); background: var(--glass); }
/* the "+ Add" adders inherit the secondary tier's tint but stay dashed and
   full-width, so they read as "extend the form" rather than "submit" */
.badd {
  font-family: var(--f-m); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ember); background: none; border: 0; cursor: pointer;
  padding: 11px 15px; border-radius: 10px; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ember) 30%, transparent);
  justify-self: start; min-height: 44px;
}
.badd:hover { background: color-mix(in srgb, var(--ember) 10%, transparent); }
.ghost-add { color: var(--dim); box-shadow: inset 0 0 0 1px var(--edge); }
.ghost-add:hover { color: var(--ink); background: var(--glass); }
.bfoot { display: flex; gap: 9px; flex-wrap: wrap; }
.gaprow { display: grid; grid-template-columns: 1.6fr 1fr; gap: 10px; }

.bullet-notes { display: grid; gap: 6px; }
.bnote-line {
  font-size: 12px; line-height: 1.55; padding: 8px 11px; border-radius: 9px;
  color: var(--ink-2); background: var(--glass); border-left: 2px solid var(--gold);
}
.bnote-line[data-tone="bad"] { border-left-color: var(--ember); }

/* ── right: preview + score ──────────────────────────────────────────────── */
.bside {
  overflow-y: auto; border-left: 1px solid var(--edge);
  background: color-mix(in srgb, var(--page) 55%, transparent);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  padding: 18px 16px calc(24px + env(safe-area-inset-bottom));
  display: grid; gap: 14px; align-content: start;
}
.bscore { display: flex; align-items: center; gap: 14px; }
.bscore-n { display: flex; align-items: baseline; gap: 4px; }
.bscore-n b {
  font-family: var(--f-d); font-size: 44px; font-weight: 700; letter-spacing: -.05em; line-height: 1;
}
.bscore-n span { font-family: var(--f-m); font-size: 12px; color: var(--dim); }
.bscore-meta { flex: 1; display: grid; gap: 7px; }
.bscore-meta p { font-size: 11.5px; line-height: 1.5; color: var(--dim); }
.bmeter { display: flex; gap: 2px; height: 16px; align-items: flex-end; }
.bmeter i { flex: 1; height: 40%; border-radius: 2px; background: var(--edge); }
.bmeter i.on { height: 100%; }
.bmeter i.on[data-z="bad"] { background: var(--fx-red); }
.bmeter i.on[data-z="warn"] { background: var(--fx-gold); }
.bmeter i.on[data-z="good"] { background: var(--fx-green); }

.btabs { display: flex; gap: 3px; padding: 3px; }
.btab {
  flex: 1; font-family: var(--f-m); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); background: none; border: 0; cursor: pointer; padding: 9px 6px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-height: 38px;
}
.btab.on { color: var(--on-ink); background: var(--ink); }
.btab:not(.on):hover { color: var(--ink); background: var(--glass); }
.btab.on:hover { color: var(--on-ink); background: color-mix(in srgb, var(--ink) 88%, var(--ember)); }
.btab i { font-style: normal; font-size: 9px; opacity: .8; }

.bpane { display: none; }
.bpane.on { display: block; }
.bempty { font-size: 12.5px; line-height: 1.6; color: var(--dim); padding: 16px 4px; }

/* the live page - deliberately paper-like against the dark shell.
   Every --t-* value is written by build.js from the server's template spec,
   so this preview and the exported file are driven by one set of numbers. */
.paper-sheet {
  --t-font: var(--f-b); --t-accent: #1f3a5f; --t-muted: #5a5a5a;
  --t-name: 20pt; --t-name-align: left; --t-name-case: none; --t-name-color: #111;
  --t-head: 11.5pt; --t-head-color: #1f3a5f; --t-track: 0px;
  --t-body: 10.5pt; --t-lead: 1.33; --t-gap: 3pt;
  background: #fff; color: #17150f; border-radius: 4px; padding: 26px 24px;
  box-shadow: 0 20px 50px rgba(0,0,0,.4); min-height: 320px;
  /* the sheet is a scaled-down A4: point sizes are real, then shrunk as one */
  font-family: var(--t-font); font-size: calc(var(--t-body) * .74);
  line-height: var(--t-lead);
  transition: font-family .2s, color .2s;
}
.ps-name {
  font-size: calc(var(--t-name) * .74); font-weight: 700; color: var(--t-name-color);
  text-align: var(--t-name-align); text-transform: var(--t-name-case);
  letter-spacing: calc(var(--t-track) * .5); margin-bottom: 3px; line-height: 1.15;
}
.ps-contact {
  font-size: calc((var(--t-body) - 1pt) * .74); color: var(--t-muted);
  text-align: var(--t-name-align); margin-bottom: 2px;
}
.ps-h {
  font-family: inherit; font-weight: 700; font-size: calc(var(--t-head) * .74);
  letter-spacing: var(--t-track); color: var(--t-head-color);
  margin: calc(var(--t-gap) * 2.4 + 5px) 0 4px; padding-bottom: 3px;
  border-bottom: 1px solid var(--t-accent);
}
/* the rule under a heading is part of the template's identity, not decoration */
[data-rule="none"] .ps-h { border-bottom: 0; padding-bottom: 0; }
[data-rule="short"] .ps-h {
  border-bottom: 0; padding-bottom: 0; position: relative; margin-bottom: 9px;
}
[data-rule="short"] .ps-h::after {
  content: ""; position: absolute; left: 0; bottom: -5px; width: 34px; height: 1.5px;
  background: var(--t-accent);
}
.ps-line { margin-bottom: var(--t-gap); }
.paper-sheet .bempty { color: #6b675e; }   /* 3.7:1 on white failed AA */

/* ── template picker ─────────────────────────────────────────────────────── */
.tplgrid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px; }
.tplcard {
  display: flex; gap: 12px; align-items: flex-start; text-align: left;
  padding: 11px; border-radius: 12px; cursor: pointer;
  background: var(--glass); border: 0; color: inherit;
  box-shadow: inset 0 0 0 1px var(--edge);
  transition: box-shadow .18s, background .18s, transform .18s;
}
.tplcard:hover { transform: translateY(-2px); }
.tplcard.on { box-shadow: inset 0 0 0 1.5px var(--ember); background: color-mix(in srgb, var(--ember) 9%, transparent); }
.tplmeta { display: block; min-width: 0; }
.tplmeta b { display: block; font-size: 13px; margin-bottom: 3px; }
.tplmeta span { display: block; font-size: 11.5px; line-height: 1.5; color: var(--dim); }
.tplfit {
  font-family: var(--f-m); font-style: normal; font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ember); margin-left: 6px; vertical-align: 1px;
}

/* a real miniature, drawn from the same accent/alignment/rule the export uses -
   not a stock screenshot that could go stale against the generator */
.tplmini {
  flex: 0 0 46px; width: 46px; height: 62px; border-radius: 3px; background: #fff;
  padding: 6px 5px; display: flex; flex-direction: column; gap: 2.5px;
  box-shadow: 0 2px 8px rgba(0,0,0,.35); font-family: var(--m-font);
}
.tplmini i { display: block; border-radius: 1px; }
.tplmini .m-name { height: 5px; width: 68%; background: var(--m-accent); }
.tplmini .m-sub { height: 2px; width: 84%; background: #c9c4b8; margin-bottom: 2px; }
.tplmini .m-h { height: 2.5px; width: 46%; background: var(--m-accent); margin-top: 3px; }
.tplmini .m-l { height: 1.5px; width: 100%; background: #ddd8cc; }
.tplmini .m-l.s { width: 72%; }
.tplmini[data-align="center"] .m-name,
.tplmini[data-align="center"] .m-sub { margin-left: auto; margin-right: auto; }
.tplmini[data-rule="full"] .m-h { border-bottom: 1px solid var(--m-accent); padding-bottom: 1.5px; width: 100%; }
.tplmini[data-rule="none"] .m-h { width: 40%; }

.bfix {
  padding: 12px 13px; border-radius: 11px; background: var(--glass);
  box-shadow: inset 0 0 0 1px var(--edge); margin-bottom: 8px;
}
.bsev {
  font-family: var(--f-m); font-size: 8.5px; letter-spacing: .14em; text-transform: uppercase;
  padding: 3px 7px; border-radius: 5px; color: var(--ember);
  background: color-mix(in srgb, var(--ember) 14%, transparent);
}
.bfix[data-sev="medium"] .bsev { color: var(--gold); background: color-mix(in srgb, var(--gold) 14%, transparent); }
.bfix[data-sev="low"] .bsev { color: var(--dim); background: var(--glass); }
.bfix b { display: block; font-size: 13px; font-weight: 600; margin: 8px 0 4px; letter-spacing: -.012em; }
.bfix p { font-size: 12px; line-height: 1.55; color: var(--dim); }

.bfit { padding: 14px; border-radius: 12px; background: var(--glass); box-shadow: inset 0 0 0 1px var(--edge); }
.bfit-pct { font-family: var(--f-d); font-size: 32px; font-weight: 700; letter-spacing: -.045em; }
.bfit-pct[data-t="good"] { color: var(--signal); }
.bfit-pct[data-t="warn"] { color: var(--gold); }
.bfit-pct[data-t="bad"] { color: var(--ember); }
.bfit span { font-size: 12px; color: var(--dim); margin-left: 7px; }
.bfit-bar { height: 5px; border-radius: 3px; background: var(--edge); margin-top: 11px; overflow: hidden; }
.bfit-bar i { display: block; height: 100%; }
.bfit-bar i[data-t="good"] { background: var(--signal); }
.bfit-bar i[data-t="warn"] { background: var(--gold); }
.bfit-bar i[data-t="bad"] { background: var(--fx-red); }
.bfit-h {
  font-family: var(--f-m); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim); margin: 14px 0 7px;
}
.bchips { display: flex; flex-wrap: wrap; gap: 5px; }
.bchip {
  font-size: 11.5px; padding: 4px 10px; border-radius: 999px; color: var(--ember);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ember) 30%, transparent);
}
.bchip.on { color: var(--signal); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--signal) 32%, transparent); }

.bexport { display: flex; gap: 8px; }
/* layout only - .btn / .btn-primary / .btn-quiet own the look */
.bdl { flex: 1 1 0; border-radius: 12px; }
.bdl:disabled { cursor: wait; }
.bnote { font-size: 11px; line-height: 1.55; color: var(--dim); }

/* ── responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 1080px) {
  .bshell { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
  .bside {
    border-left: 0; border-top: 1px solid var(--edge);
    max-height: 52vh; position: sticky; bottom: 0;
  }
}
@media (max-width: 720px) {
  .frow.two, .frow.three, .gaprow { grid-template-columns: 1fr; }
  .bform { padding: 18px 14px 40px; gap: 24px; }
  .bside { max-height: 56vh; }
  .paper-sheet { padding: 20px 18px; }
  .tplgrid { grid-template-columns: 1fr; }
}
@media (max-height: 560px) and (orientation: landscape) {
  /* a fixed, non-resizable split - real estate here is too tight for a drag
     gesture to be worth having, and this can technically coincide with the
     min-width:1081px rule above on an unusually wide-but-short window */
  .bshell { grid-template-columns: minmax(0,1fr) minmax(300px, 380px); grid-template-rows: 1fr; }
  .bside { max-height: none; position: static; border-top: 0; border-left: 1px solid var(--edge); }
  .bdivider { display: none; }
}

/* the remove-row ✕ is a real tap target on touch, not a 28px desktop affordance */
@media (max-width: 720px) {
  .rep-x { width: 44px; height: 44px; }
}

/* skill groups are one line each - they do not need the full card padding */
.rep.slim { padding-bottom: 4px; }
.rep.slim .rep-h { margin-bottom: 6px; }


/* ── sample-first block, directly under the intro ──────────────────────────
   The single most useful action for a first-time visitor was previously the
   last control on a ten-section form. It now sits where they actually are. */
.bstart {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 22px; padding: 16px 18px; border-radius: 16px;
  background: color-mix(in srgb, var(--ember) 7%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ember) 26%, transparent);
}
.bstart-note { font-size: 12.5px; line-height: 1.5; color: var(--dim); flex: 1 1 200px; }

/* Secondary action next to "Upload an existing resume". Same geometry as
   .btn so the pair sits on one baseline, but no fill - uploading is the
   primary path now that it exists, and two solid buttons would compete. */
.btn-ghost {
  background: transparent; color: var(--ink);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 26%, transparent);
}
.btn-ghost:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 46%, transparent); }

.import-status {
  margin: 10px 2px 0; font-size: 12.5px; line-height: 1.55; color: var(--dim);
}
.import-status[data-tone="ok"] { color: var(--ink); }
.import-status[data-tone="warn"] { color: var(--ember); }
.import-status[data-tone="busy"] { opacity: .8; }

/* export row: DOCX is the primary action, PDF the alternative */
.bdl { font-size: 13.5px; min-height: 46px; }

/* tabs are chrome, but 10.5px mono was too quiet to find */
.btab { font-size: 11.5px; letter-spacing: .08em; min-height: 40px; }

@media (max-width: 720px) {
  .bstart { flex-direction: column; align-items: stretch; }
  .bstart-note { flex: none; }
}

/* Form controls were 39px tall - under the 44px touch minimum, on the one
   screen in the product where a user does nothing but tap fields. */
@media (max-width: 720px) {
  .fld input, .fld select, .fld textarea { min-height: 44px; }
  .fld textarea { min-height: 88px; }
}

/* an inline reference that is also the way to get there */
.jump {
  font: inherit; color: var(--ember); background: none; border: 0; cursor: pointer;
  padding: 2px 4px; margin: 0 -2px; border-radius: 5px;
  text-decoration: underline; text-underline-offset: 3px;
}
.jump:hover { background: color-mix(in srgb, var(--fx-red) 14%, transparent); }

/* where a jump lands - brief, so it points without shouting */
.bsec.flash { animation: stepFlash 1.5s var(--ease); border-radius: 14px; }
@keyframes stepFlash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; background: transparent; }
  12%      { box-shadow: 0 0 0 2px color-mix(in srgb, var(--fx-red) 55%, transparent);
             background: color-mix(in srgb, var(--fx-red) 8%, transparent); }
  70%      { box-shadow: 0 0 0 2px color-mix(in srgb, var(--fx-red) 30%, transparent);
             background: color-mix(in srgb, var(--fx-red) 5%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .bsec.flash { animation: none; } }

/* quiet confirmation that work is not being lost */
.save-state {
  font-family: var(--f-m); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); align-self: center; opacity: 0; transition: opacity .3s var(--ease);
}
.save-state[data-on="1"] { opacity: 1; }
.save-state[data-on="1"]::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--fx-green); margin-right: 7px; vertical-align: 1px;
}

/* the blocker line is clickable, so it should say so */
#score-state { cursor: pointer; }
#score-state:hover { color: var(--ink); }

/* "Fix in step NN" inside a finding card */
.bfix .jump { margin-top: 8px; display: inline-block; font-size: 12px; }

/* identity-number guard - loud on purpose; this one is about harm, not polish */
.id-warning {
  margin-bottom: 10px; padding: 11px 13px; border-radius: 11px;
  font-size: 12.5px; line-height: 1.55; color: var(--ink);
  background: color-mix(in srgb, var(--fx-red) 14%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fx-red) 55%, transparent);
}

/* ═══ PHONE LAYOUT ═══════════════════════════════════════════════════════════
   Not the desktop two-pane made narrower. On a phone the old layout gave a
   permanent 56vh to the preview, leaving less than half a screen to fill a
   ten-section form in - the preview was winning space from the only thing the
   user was actually doing.

   So on phones the right pane becomes a pull-up sheet: collapsed to a bar that
   still shows the live score, expanded when you want to look at the page. The
   form gets the whole screen the rest of the time. A step rail across the top
   replaces scroll-hunting, and each section ends with a thumb-reachable way
   into the next one.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .bshell { grid-template-rows: 1fr; }

  /* ── step rail ── */
  .steprail {
    display: flex; gap: 6px; overflow-x: auto; overscroll-behavior-x: contain;
    position: fixed; z-index: 30; left: 0; right: 0;
    top: calc(var(--hud-h) + env(safe-area-inset-top));
    padding: 8px 12px; scrollbar-width: none;
    background: color-mix(in srgb, var(--page) 92%, transparent);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--edge);
    scroll-padding-inline: 12px;
  }
  .steprail::-webkit-scrollbar { display: none; }
  /* the chips inherit the shared pill treatment; the rail itself stays a bar */
  .steprail button {
    flex: none; display: inline-flex; align-items: center; gap: 6px;
    transition: color .2s var(--ease), background .2s var(--ease);
    font-family: var(--f-m); font-size: 11px; letter-spacing: .06em;
    min-height: 40px; padding: 0 14px; border-radius: 999px; cursor: pointer;
    border: 0; color: var(--dim); background: var(--glass);
    box-shadow: inset 0 0 0 1px var(--edge); white-space: nowrap;
  }
  .steprail button[data-done="1"] { color: var(--ink-2); }
  .steprail button[data-done="1"]::before {
    content: "✓"; font-size: 10px; color: var(--fx-green);
  }
  .steprail button.on {
    color: var(--on-fx); background: var(--fx-red); box-shadow: none;
  }
  .steprail button.on[data-done="1"]::before { color: var(--on-fx); }

  /* the rail is fixed, so the form starts below it */
  .bform { padding-top: 62px; padding-bottom: 132px; }

  /* ── the sheet ── */
  .bside {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 35;
    max-height: none; height: auto; border-top: 1px solid var(--edge);
    border-radius: 18px 18px 0 0; padding: 0 14px;
    background: color-mix(in srgb, var(--page) 96%, transparent);
    box-shadow: 0 -18px 44px rgba(0,0,0,.42);
    transition: transform .32s var(--ease);
    display: block; overflow: hidden;
  }
  .bside > :not(.sheet-grip) { display: none; }

  .bside.open {
    top: calc(var(--hud-h) + env(safe-area-inset-top) + 44px);
    overflow-y: auto; overscroll-behavior: contain;
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
  }
  .bside.open > :not(.sheet-grip) { display: block; }
  .bside.open .bscore { display: flex; }
  .bside.open .btabs { display: flex; }
  .bside.open .bexport { display: flex; }

  /* ── the grip: collapsed, it is the score bar; expanded, the close handle ── */
  .sheet-grip {
    display: grid; width: 100%; border: 0; cursor: pointer; background: none;
    grid-template-columns: auto 1fr auto; align-items: center; gap: 12px;
    padding: 10px 2px calc(12px + env(safe-area-inset-bottom));
    color: var(--ink); text-align: left; min-height: 62px;
  }
  .bside.open .sheet-grip {
    position: sticky; top: 0; z-index: 2; padding-bottom: 10px;
    background: color-mix(in srgb, var(--page) 96%, transparent);
    border-bottom: 1px solid var(--edge); margin-bottom: 12px;
  }
  .grip-bar {
    position: absolute; top: 6px; left: 50%; transform: translateX(-50%);
    width: 36px; height: 4px; border-radius: 999px; background: var(--edge);
  }
  .grip-score { display: inline-flex; align-items: baseline; gap: 2px; }
  .grip-score b { font-family: var(--f-d); font-size: 26px; line-height: 1; letter-spacing: -.02em; }
  .grip-score i { font-family: var(--f-m); font-style: normal; font-size: 10px; color: var(--dim); }
  .grip-label { font-size: 12.5px; color: var(--dim); line-height: 1.35; }
  .grip-caret {
    width: 10px; height: 10px; border-right: 2px solid var(--dim); border-bottom: 2px solid var(--dim);
    transform: rotate(-135deg); margin-right: 6px; transition: transform .28s var(--ease);
  }
  .bside.open .grip-caret { transform: rotate(45deg); margin-bottom: 5px; }
  .bside.open .grip-bar { display: none; }
  /* the full score panel is right below once open - no need to say it twice */
  .bside.open .grip-score { display: none; }
  .bside.open .sheet-grip { grid-template-columns: 1fr auto; }

  /* the sheet owns the bottom of the screen, so the paper can be taller */
  .paper-sheet { min-height: 0; }

  /* ── next-section button at the foot of each block ── */
  .stepnext {
    display: flex; width: 100%; align-items: center; justify-content: space-between;
    gap: 10px; margin-top: 4px; min-height: 46px; padding: 12px 16px;
    border: 0; border-radius: 12px; cursor: pointer;
    font-family: var(--f-b); font-size: 13px; font-weight: 600; color: var(--ink);
    background: var(--glass); box-shadow: inset 0 0 0 1px var(--edge);
  }
  .stepnext span { color: var(--dim); font-weight: 400; font-size: 12px; }

  /* keyboard up: the sheet must not sit on top of the field being typed into */
  body.kb-open .bside { transform: translateY(110%); }
  body.kb-open .steprail { opacity: 0; pointer-events: none; }
}

/* desktop and tablet never see any of it */
@media (min-width: 721px) {
  .steprail, .sheet-grip, .stepnext { display: none !important; }
}

/* ── tab panes crossfade instead of cutting ───────────────────────────────
   display:none → block is a hard cut: the old panel vanishes and the new one
   appears in the same frame, which made the tab bar feel like a page reload
   rather than a switch. */
.bpane { display: none; }
.bpane.on {
  display: block;
  animation: paneIn .34s var(--ease) both;
}
@keyframes paneIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* rows added to Experience / Projects / Skills used to appear instantly */
.rep { animation: repIn .34s var(--spring) both; }
@keyframes repIn {
  from { opacity: 0; transform: translateY(-6px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* the score meter fills left-to-right rather than all at once */
.bmeter i { transition: background .28s var(--ease), height .3s var(--spring); }
.bmeter i.on { transition-delay: calc(var(--n, 0) * 14ms); }

/* advice lines change constantly as the form is filled - fade the swap */
.advice { transition: color .2s var(--ease), border-color .2s var(--ease); }
.advice[data-tone] { animation: adviceIn .3s var(--ease) both; }
@keyframes adviceIn { from { opacity: 0; transform: translateY(-3px); } }

@media (prefers-reduced-motion: reduce) {
  .bpane.on, .rep, .advice[data-tone] { animation: none; }
  .bmeter i, .bmeter i.on { transition: none; }
}

/* ── preview pane reveal ───────────────────────────────────────────────────
   Arriving on the builder from another page, the right-hand pane used to
   pop in fully-formed at whatever width/scroll it settled on - a visible
   snap right as the page appeared. It now rises in from the bottom, which
   also covers the moment where the live score and paper are still being
   assembled. Composited-only (opacity/transform), so it costs nothing and
   runs at whatever refresh rate the display uses.

   `both` is deliberately NOT used: if this animation never runs the pane
   must still be visible, the same lesson as the hero text reveal. */
/* Gated on .reveal-ok, which build.js adds ONLY when the page is confirmed
   visible. A CSS animation is paused in a background tab, which pins the
   element at its `from` keyframe - opacity 0 - so an unconditional reveal
   can leave the whole preview pane invisible until something resumes it.
   Same lesson as the hero text: an animation must never be the thing that
   decides whether content exists. No animation = pane simply visible. */
@media (prefers-reduced-motion: no-preference) {
  .reveal-ok .bside { animation: bsideIn .52s cubic-bezier(.22,.8,.2,1); }
  @keyframes bsideIn {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: none; }
  }
  /* the paper itself follows a beat later so the pane frames it first */
  .reveal-ok .paper-sheet { animation: paperIn .55s cubic-bezier(.22,.8,.2,1) .10s backwards; }
  @keyframes paperIn {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
  }
}

/* Same reasoning as the via-transition block in style.css: when the builder
   is reached by clicking a link, the view transition has already presented
   the page, so the pane must not then perform its own separate entrance. */
html.via-transition .bside,
html.via-transition .paper-sheet {
  /* delay removed, duration kept - the pane still rises from the bottom,
     it just doesn't wait to start */
  animation-delay: 0s !important;
}

/* ── template fold ───────────────────────────────────────────────────────── */
.tplmore {
  grid-column: 1 / -1; justify-self: start;
  font: inherit; font-size: 13px; color: var(--ink); cursor: pointer;
  background: transparent; border: 0; border-radius: 10px; padding: 10px 14px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 26%, transparent);
  transition: box-shadow .16s var(--ease);
}
.tplmore:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 46%, transparent); }
.tplphoto {
  font-style: normal; font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 999px; margin-left: 4px;
  background: color-mix(in srgb, var(--ink) 12%, transparent); color: var(--dim);
}

/* mini-preview additions so the cards actually differ from each other */
.tplmini .m-sub.xs { width: 38%; }
.tplmini .m-photo {
  position: absolute; top: 6px; right: 6px; width: 13px; height: 16px;
  border-radius: 2px; background: color-mix(in srgb, var(--m-accent) 30%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--m-accent) 55%, transparent);
}
.tplmini { position: relative; }
.tplmini[data-shade="1"] .m-h {
  background: var(--m-headshade, transparent); box-shadow: none;
  padding: 1px 3px; border-radius: 2px;
}
.tplmini[data-band="1"] .m-name,
.tplmini[data-band="1"] .m-sub { background-color: var(--m-nameshade, transparent); }

/* ── passport photo ──────────────────────────────────────────────────────── */
.photorow {
  display: flex; gap: 16px; align-items: flex-start; margin-top: 18px;
  padding: 16px; border-radius: 14px;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  box-shadow: inset 0 0 0 1px var(--edge);
}
.photoprev {
  flex: 0 0 auto; width: 74px; height: 92px; border-radius: 8px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  background-size: cover; background-position: center;
  box-shadow: inset 0 0 0 1px var(--edge);
}
.photoprev.has { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ember) 45%, transparent); }
.photoctl { flex: 1 1 auto; min-width: 0; }
.photoctl b { display: block; font-size: 13.5px; margin-bottom: 4px; }
.photoctl p { font-size: 12.5px; line-height: 1.55; color: var(--dim); margin: 0 0 10px; }
.photobtns { display: flex; gap: 8px; flex-wrap: wrap; }
.photonote { font-size: 12px; margin-top: 8px !important; }
.photonote[data-tone="ok"] { color: var(--ink); }
.photonote[data-tone="warn"] { color: var(--ember); }

/* The photo as it actually sits on the exported sheet: its own right-aligned
   block ABOVE the name. Deliberately not float:right - build_docx puts the
   image in a standalone right-aligned paragraph (a table cell or a floating
   frame is exactly what scrambles a parser), so nothing wraps beside it.
   Floating it here made the preview promise a layout the download never had. */
.ps-photo {
  display: block; width: 76px; margin: 0 0 8px auto; border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.18);
}

/* ── target length ───────────────────────────────────────────────────────── */
/* The advice used to be a flex SIBLING of the buttons with align-items:center,
   so every message length change resized the row and re-centred the control -
   picking "2 pages" (a 12-word message) lifted the buttons 10px off the page
   while the pointer was still on them. The control line and the advice line
   are now separate rows, and the advice reserves the height of its longest
   message, so nothing above it can move no matter what is clicked. */
.lenrow {
  display: grid; grid-template-columns: auto auto; justify-content: start;
  align-items: center; gap: 10px 12px; margin-top: 18px;
}
/* The segment sat in a 1fr column, so a three-word control was stretched the
   full width of the form - a pill the size of a banner. It hugs its content
   now; only the advice line below spans. */
.lenseg { justify-self: start; }
.lenrow .advice {
  grid-column: 1 / -1; margin: 0;
  /* Measured, not guessed: line-height here is 20px and the longest of the
     length messages runs to three lines, so 60px is the tallest this box ever
     needs. Reserving it means neither the control above nor the section below
     moves when the message changes. */
  min-height: 60px;
  display: flex; align-items: center;
}
@media (max-width: 620px) {
  .lenrow { grid-template-columns: auto; }
  /* narrower column, so the same text wraps further */
  .lenrow .advice { min-height: 100px; }
}
.lenlab {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim);
}
.lenseg {
  display: inline-flex; padding: 3px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  box-shadow: inset 0 0 0 1px var(--edge);
}
.lenseg button {
  font: inherit; font-size: 12.5px; cursor: pointer; color: var(--dim);
  background: transparent; border: 0; border-radius: 999px; padding: 6px 14px;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.lenseg button.on { background: var(--ink); color: var(--page); }
.lenseg button:not(.on):hover { color: var(--ink); }

@media (max-width: 620px) {
  .photorow { flex-direction: column; }
  .lenrow { justify-items: start; }
}

/* The reserved photo slot, shown before anything is uploaded. Same box model
   as .ps-photo so the text wraps around exactly where it will in the export -
   the slot is the point, not the picture. */
.ps-photo-empty {
  display: flex; align-items: center; justify-content: center; text-align: center;
  margin-left: auto;
  height: 95px; box-sizing: border-box;
  font-size: 8px; line-height: 1.35; letter-spacing: .06em; text-transform: uppercase;
  /* --t-muted is the sheet's own muted ink and is set per template, so the
     slot picks up each template's colour instead of a hardcoded grey. */
  color: var(--t-muted, #5a5a5a);
  background: rgba(0, 0, 0, .035);
  box-shadow: none;
  outline: 1px dashed color-mix(in srgb, var(--t-muted, #5a5a5a) 55%, transparent);
  outline-offset: -1px;
}

/* ── import progress ─────────────────────────────────────────────────────── */
.import-status { display: flex; align-items: flex-start; gap: 9px; font-size: 12.5px;
  line-height: 1.55; color: var(--dim); margin-top: 12px; }
.import-status[data-tone="ok"]   { color: var(--ink); }
.import-status[data-tone="warn"] { color: var(--ember); }
.import-status[data-tone="busy"] { color: var(--ink); }
.spin {
  flex: 0 0 auto; width: 13px; height: 13px; margin-top: 3px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--ink) 22%, transparent);
  border-top-color: var(--ember);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  /* Still needs to read as "working" without spinning: pulse the ring instead. */
  .spin { animation: spinPulse 1.1s ease-in-out infinite; }
  @keyframes spinPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
}

/* ── keep-my-own-layout ──────────────────────────────────────────────────── */
.ownmode {
  margin-top: 14px; padding: 14px 16px; border-radius: 14px;
  background: color-mix(in srgb, var(--ember) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ember) 24%, transparent);
}
.ownmode-toggle { display: flex; gap: 12px; align-items: flex-start; cursor: pointer; }
.ownmode-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.ownmode-track {
  flex: 0 0 auto; width: 40px; height: 23px; margin-top: 1px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 16%, transparent);
  box-shadow: inset 0 0 0 1px var(--edge);
  transition: background .18s var(--ease);
  position: relative;
}
.ownmode-track i {
  position: absolute; top: 3px; left: 3px; width: 17px; height: 17px; border-radius: 50%;
  background: var(--ink); transition: transform .18s var(--spring);
}
.ownmode-toggle input:checked + .ownmode-track { background: var(--ember); }
.ownmode-toggle input:checked + .ownmode-track i { transform: translateX(17px); background: #fff; }
.ownmode-toggle input:focus-visible + .ownmode-track {
  outline: 2px solid var(--ember); outline-offset: 2px;
}
.ownmode-label b { display: block; font-size: 13.5px; margin-bottom: 3px; }
.ownmode-label span { font-size: 12.5px; line-height: 1.55; color: var(--dim); }

.ownedit { margin-top: 18px; }
.ownedit textarea {
  font-family: var(--f-m, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 12.5px; line-height: 1.6; min-height: 420px; white-space: pre-wrap;
}

/* ── the uploaded document's own layout, reproduced ──────────────────────── */
.ps-own { margin: 0; white-space: pre-wrap; word-break: break-word; }
.ps-own-bul { position: relative; padding-left: 14px; }
.ps-own .ps-b { position: absolute; left: 0; }

/* ── page-count readout above the sheet ──────────────────────────────────── */
.sheetmeta {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 0 0 8px; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--dim);
}
.sheetpages { font-weight: 600; color: var(--ink); }
.sheetmeta[data-tone="warn"] .sheetpages { color: var(--gold, #d9a441); }
.sheetnote { text-transform: none; letter-spacing: 0; font-size: 11.5px; }

/* ── own-mode: no captured design ────────────────────────────────────────── */
.ownwarn {
  margin: 12px 0 0; padding: 11px 13px; border-radius: 10px;
  font-size: 12.5px; line-height: 1.55; color: var(--ink-2, var(--ink));
  background: color-mix(in srgb, var(--gold, #d9a441) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold, #d9a441) 32%, transparent);
}

/* ══ typography controls, own-layout mode ═══════════════════════════════════
   Word and Pages give you a font menu with two hundred faces and no opinion
   about any of them. Half of those break a PDF parser, and nothing on screen
   tells you which. Every control here states its consequence instead, and the
   page count under it moves as you drag - which is the number people are
   actually trying to control when they reach for line spacing. */
/* Controls that only mean something in one of the two modes are hidden in the
   other rather than shown inert: a template decides its own weights and
   alignment, and an imported layout has no template heading size. */
.typo[data-mode="tmpl"] .typo-lines,
.typo[data-mode="own"] .typo-tmpl { display: none; }
.typo[data-mode="tmpl"] .typo-scope { cursor: default; }
.typo {
  border-radius: 16px; padding: 13px 14px 12px; margin: 14px 0 0;
  background: var(--glass); box-shadow: inset 0 0 0 1px var(--edge);
}
.typo-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.typo-scope {
  font-family: var(--f-m); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--on-fx); background: var(--fx-red); padding: 5px 10px; border-radius: 999px;
  border: 0; cursor: pointer; transition: filter .18s var(--ease);
}
.typo-scope:hover { filter: brightness(1.12); }
.typo-scope[aria-pressed="false"] {
  color: var(--ink); background: none; box-shadow: inset 0 0 0 1px var(--fx-red);
}
.typo-hint { font-size: 11.5px; color: var(--dim); }
.typo-row { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; }
.typo-grp { display: grid; gap: 6px; }
.typo-grp-wide { flex: 1 1 190px; min-width: 160px; }
.typo-k {
  font-family: var(--f-m); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim); display: flex; align-items: baseline; gap: 6px;
}
.typo-k output { color: var(--ink-2); letter-spacing: .06em; }

.typo-faces { display: flex; gap: 5px; }
.typo-faces { flex-wrap: wrap; }
.typo-faces button {
  display: grid; place-items: center; gap: 1px; cursor: pointer;
  width: 54px; padding: 5px 0 6px; border: 0; border-radius: 10px;
  background: none; box-shadow: inset 0 0 0 1px var(--edge); color: var(--ink-2);
  font-size: 15px; line-height: 1.1;
  transition: color .18s var(--ease), background .18s var(--ease), box-shadow .18s var(--ease);
}
.typo-faces button i {
  font-style: normal; font-family: var(--f-m); font-size: 8.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--dim);
}
.typo-faces button:hover { color: var(--ink); background: var(--glass); }
.typo-faces button.on { color: var(--on-fx); background: var(--fx-red); box-shadow: none; }
.typo-faces button.on i { color: inherit; opacity: .8; }

.typo-step, .typo-seg { display: flex; align-items: stretch; gap: 3px; }
.typo-step button, .typo-seg button {
  min-width: 32px; height: 32px; cursor: pointer; border: 0; border-radius: 9px;
  background: none; box-shadow: inset 0 0 0 1px var(--edge); color: var(--ink-2);
  font: inherit; font-size: 13px; display: grid; place-items: center;
  transition: color .18s var(--ease), background .18s var(--ease);
}
.typo-step button:hover, .typo-seg button:hover { color: var(--ink); background: var(--glass); }
.typo-seg button.on { color: var(--on-fx); background: var(--fx-red); box-shadow: none; }
.typo-step output {
  min-width: 52px; height: 32px; display: grid; place-items: center;
  font-family: var(--f-m); font-size: 12px; color: var(--ink);
  border-radius: 9px; box-shadow: inset 0 0 0 1px var(--edge);
  font-variant-numeric: tabular-nums;
}
.typo-b { font-weight: 800; }
.typo-i { font-style: italic; font-family: Georgia, serif; }

#typo-ls {
  -webkit-appearance: none; appearance: none; width: 100%; height: 32px;
  background: none; cursor: pointer;
}
#typo-ls::-webkit-slider-runnable-track { height: 3px; border-radius: 2px; background: var(--edge); }
#typo-ls::-moz-range-track { height: 3px; border-radius: 2px; background: var(--edge); }
#typo-ls::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 15px; height: 15px; margin-top: -6px;
  border-radius: 50%; background: var(--fx-red); border: 0;
}
#typo-ls::-moz-range-thumb { width: 15px; height: 15px; border-radius: 50%; background: var(--fx-red); border: 0; }
#typo-ls:focus-visible { outline: 2px solid var(--fx-red); outline-offset: 3px; }

.typo-reset {
  align-self: flex-end; height: 32px; padding: 0 12px; cursor: pointer;
  border: 0; border-radius: 9px; background: none; box-shadow: inset 0 0 0 1px var(--edge);
  color: var(--dim); font-family: var(--f-m); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; transition: color .18s var(--ease);
}
.typo-reset:hover { color: var(--ink); }

.typo-note {
  margin: 11px 0 0; font-size: 12px; line-height: 1.55; color: var(--dim);
  border-top: 1px solid var(--edge); padding-top: 10px; min-height: 1.55em;
}
.typo-note b { color: var(--ink); font-weight: 600; }
.typo-note[data-tone="warn"] b { color: var(--fx-gold); }
.typo-note[data-tone="bad"] b { color: var(--fx-red); }

@media (max-width: 760px) {
  .typo-row { gap: 12px; }
  .typo-grp-wide { flex-basis: 100%; }
}

/* Phone: the same trade as style.css - these two panels sit over the shader
   and are on screen while the form scrolls behind them. */
@media (pointer: coarse) {
  .bside, .steprail {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}
