.assessment-header{max-width:var(--page);margin:auto;height:75px;display:flex;align-items:center;justify-content:space-between;padding:0 25px}.assessment-header>span{font-size:12px;color:#74687c;font-weight:700}.assessment-header>a:last-child{color:#74687c;font-size:12px}.assessment{width:100%;max-width:var(--page);margin:0 auto;padding:44px max(20px,3vw) 90px}.progress{height:5px;border-radius:5px;background:#e7e0ec;margin-bottom:52px;overflow:hidden}.progress i{display:block;height:100%;background:var(--coral);width:0;transition:.3s}.assessment h1{font:600 45px/.99 'Fraunces',serif;letter-spacing:-1.7px;margin:0}.assessment h1 em{font-style:italic;color:var(--coral)}.assessment .intro{color:#716577;line-height:1.6;font-size:16px;max-width:560px;margin:20px 0}.callout{border-left:3px solid var(--coral);padding:4px 0 4px 15px;color:#665a70;font-size:13px;line-height:1.5;margin:28px 0}.question-count{color:#887a94;font-size:11px;letter-spacing:1.4px;font-weight:700}.question{font:600 27px/1.2 'Fraunces',serif;margin:13px 0 23px}.answers{display:grid;gap:9px}.answers label,.option{position:relative;border:1px solid #dfd7e5;background:white;border-radius:7px;padding:14px 16px;cursor:pointer;color:#594e60;font-size:14px;transition:.15s}.answers input,.option input{position:absolute;opacity:0}.answers label:has(input:checked),.option:has(input:checked){border-color:var(--coral);background:#fff8f5;color:var(--plum)}.answer-scale{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin:8px 0 30px}.answer-scale label{font-size:11px;text-align:center}.answer-scale label span{display:block;border:1px solid #dfd7e5;border-radius:50%;height:37px;width:37px;line-height:37px;margin:auto}.answer-scale label:has(input:checked) span{background:var(--plum);color:#fff;border-color:var(--plum)}.scale-caption{display:flex;justify-content:space-between;color:#83788a;font-size:10px;margin-top:-24px}.next-row{display:flex;justify-content:space-between;align-items:center;margin-top:41px}.back{border:0;background:none;color:#756a7b;font-size:13px}.next:disabled{opacity:.45;cursor:not-allowed}.preference-group{margin:28px 0}.preference-group h3{font:600 21px 'Fraunces',serif;margin:0 0 7px}.preference-group>p{font-size:13px;color:#756a7d;margin:0 0 12px}.option-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.results{background:white;border-radius:12px;padding:35px;box-shadow:0 10px 36px #41295810}.trait-row{display:grid;grid-template-columns:120px 1fr 35px;gap:12px;align-items:center;margin:17px 0;font-size:13px}.trait-row i{height:7px;background:#eee7f1;border-radius:6px;overflow:hidden}.trait-row i b{display:block;height:100%;background:var(--coral);border-radius:6px}.results .disclaimer{margin-top:30px;color:#776b7c;font-size:11px;line-height:1.55}.results a{color:var(--plum);font-weight:700}@media(max-width:560px){.assessment{margin-top:37px}.assessment h1{font-size:37px}.answer-scale{gap:2px}.option-grid{grid-template-columns:1fr}.assessment-header>span{display:none}.trait-row{grid-template-columns:100px 1fr 30px}}

/* ============================================================
   Dating Fingerprint — check-in runner, charts, constellation.
   Appended as a readable block; the rules above this line are
   the original single-line minified sheet.
   ============================================================ */

/* --- particle layer (fixed so particles never affect layout) --- */
.fp-layer{position:fixed;inset:0;pointer-events:none;z-index:60;overflow:hidden}
.fp-heart{position:absolute;bottom:8%;color:#ed7662;font-style:normal;line-height:1;
  animation:fp-rise 2.6s cubic-bezier(.3,.7,.4,1) forwards}
@keyframes fp-rise{
  0%{transform:translate(0,0) scale(.5) rotate(0);opacity:0}
  12%{opacity:1}
  100%{transform:translate(var(--drift,0),-62vh) scale(1.15) rotate(18deg);opacity:0}}
.fp-spark{position:absolute;left:50%;top:50%;border-radius:50%;pointer-events:none;
  animation:fp-burst 1.4s cubic-bezier(.2,.7,.3,1) forwards}
@keyframes fp-burst{
  0%{transform:translate(-50%,-50%) scale(.2);opacity:0}
  18%{opacity:1}
  100%{transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(.5);opacity:0}}

/* --- one question at a time --- */
.q-stage{max-width:660px;margin:0 auto;text-align:center}
.q-rail{height:5px;border-radius:3px;background:#ece4f2;overflow:hidden;margin:14px 0 26px}
.q-rail i{display:block;height:100%;border-radius:3px;background:var(--mc,#ed7662);
  transition:width .45s cubic-bezier(.2,.8,.3,1)}
.q-note{min-height:20px;margin:0 0 20px;font:italic 14px/1.4 'Fraunces',Georgia,serif;color:#8a7b95}
.q-note.fresh{animation:fp-note .7s ease both}
@keyframes fp-note{0%{opacity:0;transform:translateY(7px)}100%{opacity:1;transform:none}}
.q-statement{font:600 clamp(26px,4vw,38px)/1.18 'Fraunces',Georgia,serif;letter-spacing:-1.2px;
  color:#39234d;margin:0 0 10px}
.q-help{font-size:13px;color:#8a7b95;margin:0 0 26px}
.q-scale{display:grid;grid-template-columns:repeat(5,1fr);gap:9px}
.q-scale button{display:flex;flex-direction:column;align-items:center;gap:7px;padding:16px 6px 13px;
  border:1.5px solid #e3d9e9;border-radius:11px;background:#fff;color:#594d65;cursor:pointer;
  transition:transform .16s,border-color .16s,background .16s,box-shadow .16s}
.q-scale button b{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;
  background:#f4eefa;color:#402c68;font-size:14px}
.q-scale button span{font-size:10px;line-height:1.25;font-weight:600}
.q-scale button:hover{transform:translateY(-3px);border-color:var(--mc,#ed7662);
  box-shadow:0 10px 20px rgba(57,35,77,.11)}
.q-scale button:hover b{background:var(--mc,#ed7662);color:#fff8f5}
.q-foot{display:flex;justify-content:space-between;margin-top:30px}

/* --- hub --- */
.hub-lede{max-width:560px;color:#756a7c;line-height:1.6}
/* The whorl now carries labels outside its ring, so it needs real width: at 330px the
   drawing was squeezed to make room for text that stays a fixed size on screen. */
.hub-print{width:100%;max-width:520px;margin:26px auto 6px}
.hub-print svg{display:block;width:100%;height:auto}





/* --- charts --- */
.fp-web{fill:none;stroke:#e2d7ec;stroke-width:1}
.fp-spoke{stroke:#e8dff0;stroke-width:1}
.fp-axis{font-weight:600;font-family:'DM Sans',sans-serif;font-size:var(--fp-axis,10px);fill:#6b5f76}
.fp-pole{font-size:var(--fp-pole,9px);fill:#9a8ea4}
.fp-val{font-weight:700;font-family:'DM Sans',sans-serif;font-size:var(--fp-val,11px);fill:#39234d}
.fp-barval{font-size:10px}
.fp-track{fill:#efe8f4}
.fp-rail{stroke:#e2d7ec;stroke-width:4;stroke-linecap:round}
.fp-sector{font-weight:700;font-family:'DM Sans',sans-serif;font-size:var(--fp-sector,9px);letter-spacing:.4px}
.fp-core-n{font-weight:700;font-family:'Fraunces',serif;font-size:var(--fp-core-n,17px);fill:#39234d}
.fp-core-l{font-weight:600;font-family:'DM Sans',sans-serif;font-size:var(--fp-core-l,8px);fill:#9a8ea4}
.chart-card{position:relative;margin:22px 0;padding:20px;background:#fff;border:1px solid #ece4f2;
  border-radius:14px;box-shadow:0 12px 30px rgba(57,35,77,.07)}
.chart-host{position:relative;max-width:340px;margin:0 auto}
.chart-host svg{display:block;width:100%;height:auto;overflow:visible}
.fp-radar .fp-shape{filter:drop-shadow(0 4px 12px rgba(64,44,104,.22))}
.fp-radar .fp-nodes circle{animation:fp-pulse 2.6s ease-in-out infinite}
.fp-radar .fp-nodes circle:nth-child(2){animation-delay:.35s}
.fp-radar .fp-nodes circle:nth-child(3){animation-delay:.7s}
.fp-radar .fp-nodes circle:nth-child(4){animation-delay:1.05s}
.fp-radar .fp-nodes circle:nth-child(5){animation-delay:1.4s}
@keyframes fp-pulse{0%,100%{r:4.5;opacity:1}50%{r:6.2;opacity:.82}}

/* --- results --- */
.score-list{margin:6px 0 20px}
.score-row{display:grid;grid-template-columns:132px 1fr 34px;align-items:center;gap:12px;
  padding:7px 0;font-size:13px;color:#493d54}
.score-row i{display:block;height:9px;border-radius:5px;background:#efe8f4;overflow:hidden}
.score-row i b{display:block;height:100%;border-radius:5px;
  animation:fp-grow 1s cubic-bezier(.2,.8,.3,1) both}
@keyframes fp-grow{from{width:0!important}}
.score-row strong{text-align:right;font-size:13px;color:#39234d}
.reveal-row{display:flex;gap:11px;align-items:flex-start;padding:14px;border:1px solid #e3d9e9;
  border-radius:10px;background:#faf7fc;cursor:pointer}
.reveal-row input{position:relative;width:auto;height:auto;margin:2px 0 0;flex:none}
.reveal-row small{display:block;color:#7a6e81;font-size:11px;margin-top:3px;font-weight:400}
.next-up{margin:26px 0 20px;padding:20px;border:1px dashed #d7c7ed;border-radius:12px;background:#faf7fc}
.next-up h3{font:600 20px 'Fraunces',serif;margin:0 0 4px;color:#39234d}
.next-up p{margin:0 0 14px;font-size:13px;color:#756a7c}
.next-up.complete{border-style:solid;border-color:#c3e6cd;background:#f2faf4}
.next-grid{display:flex;flex-wrap:wrap;gap:9px}
.next-chip{display:flex;align-items:center;gap:9px;padding:11px 14px;border:1.5px solid var(--mc);
  border-radius:10px;background:#fff;cursor:pointer;transition:transform .18s,box-shadow .18s}
.next-chip:hover{transform:translateY(-3px);box-shadow:0 10px 20px rgba(57,35,77,.12)}
.next-chip span{font-size:19px;color:var(--mc)}
.next-chip b{font:700 13px 'DM Sans',sans-serif;color:#39234d}
.next-chip small{color:#8a7b95;font-size:10px}
.result-actions{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:22px}

/* --- constellation (overall fingerprint page) -------------------------------
   Every card was sizing itself to its own content, so a charted card, an empty
   card and a two-line title all produced different heights and nothing lined up.
   Three rules fix it: columns are grids with equal rows, cards are flex columns
   with the footer pinned to the bottom, and the chart slot is a fixed-ratio box
   so a radar and a "not taken yet" state occupy exactly the same space. */
.fp-title{font:600 clamp(34px,5vw,46px)/.98 'Fraunces',serif;margin:0;color:#39234d}
.fp-title em{font-style:italic;color:#ed7662}
/* Wide enough for the radar's own edge labels. The old 3-column split left the side cards
   at ~286px, where a name like "Emotional steadiness" cannot sit beside the cap at any
   readable size — which is why they had been exiled to a list underneath. */
/* min(380px,100%) rather than a bare 380px: a fixed track floor cannot shrink, so on a
   390px phone the card overflowed the screen by its own padding. */
.constellation{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(380px,100%),1fr));
  gap:18px;align-items:stretch;margin:28px 0}
.con-col{display:contents;grid-auto-rows:1fr;gap:16px;min-width:0}
.con-card{display:flex;flex-direction:column;min-width:0;
  padding:16px;border:1px solid #ece4f2;border-radius:14px;background:#fff;
  box-shadow:0 10px 26px rgba(57,35,77,.06)}
.con-card.core{border-color:var(--mc);box-shadow:0 18px 44px rgba(57,35,77,.13)}
.con-card header{display:flex;align-items:flex-start;gap:12px;min-height:52px;margin-bottom:10px}
.con-glyph{display:grid;place-items:center;width:34px;height:34px;border-radius:50%;flex:none;
  background:color-mix(in srgb,var(--mc) 16%,#fff);color:var(--mc);font-size:17px}
.con-card header>div{min-width:0}
/* The card title names the chart under it, so it has to be readable at a glance — it was
   set smaller than the numbers inside the drawing. */
.con-card strong{display:block;font:600 21px/1.15 'Fraunces',serif;color:#39234d;
  text-wrap:balance;overflow-wrap:anywhere}
.con-card small{display:block;font-size:12.5px;line-height:1.4;color:#8a7b95;margin-top:3px}
/* The slot a chart, an artifact or an empty state all sit in — same box either way. */
/* The chart's viewBox is square, so the slot is square too: at 1/.86 with height:auto the SVG
   grew taller than its box and — with overflow visible — painted over the reveal pill under it. */
.con-chart,.con-artifact,.con-empty{display:grid;place-items:center;width:100%;
  aspect-ratio:1;min-height:0;padding:2px}

/* Fit INSIDE the slot and let preserveAspectRatio centre it. The viewBox already contains
   the labels and the outermost bubble, so nothing needs to escape any more. */
.con-chart svg{display:block;width:100%;height:100%;overflow:hidden}
.con-artifact{align-content:center;text-align:left}
.con-card.empty{background:#faf7fc;border-style:dashed}
.con-empty{text-align:center;gap:12px}
.con-empty p{margin:0;font-size:12px;color:#9a8ea4}
.con-empty .button{padding:11px 15px;font-size:12.5px;white-space:nowrap}
.reveal-pill{display:flex;align-items:center;justify-content:center;gap:7px;margin-top:auto;
  padding:9px;border-radius:8px;background:#f4eefa;cursor:pointer;font:600 11px 'DM Sans',sans-serif;
  color:#6b5f76;transition:background .2s,color .2s}
.reveal-pill.on{background:color-mix(in srgb,var(--mc) 16%,#fff);color:var(--mc)}
.reveal-pill input{position:absolute;opacity:0;width:auto;height:auto}
.privacy-summary{padding:16px 18px;border:1px solid #e3d9e9;border-radius:12px;background:#faf7fc}
.privacy-summary strong{display:block;font:600 15px 'Fraunces',serif;color:#39234d;margin-bottom:4px}
.privacy-summary p{margin:0;font-size:13px;color:#756a7c}
.privacy-summary em{font-style:normal;font-weight:700;color:#402c68}




@media(max-width:560px){
  .q-scale{grid-template-columns:repeat(5,1fr);gap:5px}
  .q-scale button{padding:12px 3px 10px}
  .q-scale button span{font-size:8px}
  .q-scale button b{width:25px;height:25px;font-size:12px}
  .score-row{grid-template-columns:100px 1fr 30px;gap:8px;font-size:12px}
}
@media(prefers-reduced-motion:reduce){
  .fp-radar .fp-nodes circle{animation:none}
  .score-row i b{animation:none}
  .q-note.fresh{animation:none}
}

/* ============================================================
   Fingerprint Studio — creative input modules
   ============================================================ */
.q-stage.studio{max-width:760px}
.studio .q-statement{font-size:clamp(24px,3.4vw,32px)}
.studio-hint{margin:14px 0 0;font-size:12.5px;color:#8a7b95;min-height:18px}
.q-stage.studio .q-foot{margin-top:26px;align-items:center}

/* six-word ad */
.word-row{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-top:24px}
.word-in{width:100%;padding:14px 6px;border:1.5px solid #e3d9e9;border-radius:10px;background:#fff;
  text-align:center;font:600 15px 'DM Sans',sans-serif;color:#39234d;transition:.15s}
.word-in:focus{outline:none;border-color:var(--mc,#ed7662);box-shadow:0 0 0 3px rgba(237,118,98,.15)}
.word-in::placeholder{color:#cbc0d4;font-weight:400}
.examples{margin-top:22px;padding:14px 16px;background:#faf7fc;border-radius:10px;text-align:left}
.examples span{display:block;font:700 10px 'DM Sans',sans-serif;letter-spacing:.1em;
  text-transform:uppercase;color:#9a8ea4;margin-bottom:7px}
.examples em{display:block;font:italic 14px/1.6 'Fraunces',Georgia,serif;color:#6b5f76}

/* two-person weather */
.sentence-set{display:grid;gap:14px;margin-top:24px;text-align:left}
.sentence span{display:block;font:600 14px 'DM Sans',sans-serif;color:#4b4055;margin-bottom:6px}
.sentence textarea{width:100%;padding:12px 14px;border:1.5px solid #e3d9e9;border-radius:10px;
  background:#fff;font:400 15px/1.55 'DM Sans',sans-serif;color:#39234d;resize:vertical}
.sentence textarea:focus{outline:none;border-color:var(--mc,#5b8fd9);
  box-shadow:0 0 0 3px rgba(91,143,217,.15)}

/* social battery */
.curve-preview{margin:22px auto 4px;max-width:420px}
.curve-set{display:grid;gap:5px;margin-top:12px;text-align:left}
.curve-day{display:grid;grid-template-columns:44px 1fr 38px;align-items:center;gap:12px}
.curve-day span{font:700 11px 'DM Sans',sans-serif;color:#6b5f76}
.curve-day input[type=range]{width:100%;accent-color:var(--mc,#2f8f7d)}
.curve-day output{font:700 12px 'DM Sans',sans-serif;color:#39234d;text-align:right;
  font-variant-numeric:tabular-nums}
.fp-curve .fp-line{filter:drop-shadow(0 3px 8px rgba(47,143,125,.25))}

/* ideal saturday */
.timeline{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:24px}
.slot{border:1.5px dashed #ddd4e4;border-radius:12px;padding:12px;background:#fff;text-align:left;
  cursor:pointer;transition:.15s;min-height:118px}
.slot.active{border-style:solid;border-color:var(--mc,#d98324);background:#fffaf3}
.slot header{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:9px}
.slot header b{font:600 14px 'Fraunces',serif;color:#39234d}
.slot header small{font-size:9.5px;font-weight:700;color:#a99cba;text-transform:uppercase;letter-spacing:.06em}
.slot-items{display:flex;flex-direction:column;gap:6px}
.slot-empty{font-size:11px;color:#b5a8c0}
.chosen-act{display:flex;align-items:center;justify-content:space-between;gap:6px;width:100%;
  border:0;border-radius:8px;padding:8px 10px;background:var(--mc,#d98324);color:#fff;
  font:600 11.5px 'DM Sans',sans-serif;text-align:left;cursor:pointer}
.chosen-act b{opacity:.75;font-size:13px}
.act-palette{display:flex;flex-wrap:wrap;gap:6px;margin-top:16px;justify-content:center}
.act{border:1.5px solid #e3d9e9;border-radius:20px;padding:9px 13px;background:#fff;color:#5c5167;
  font:600 12px 'DM Sans',sans-serif;cursor:pointer;transition:.15s}
.act:hover:not(:disabled){border-color:var(--mc,#d98324);color:#8a5210}
.act.used{background:#f3eef8;color:#b5a8c0;border-color:#ece4f2}
.act:disabled{cursor:not-allowed;opacity:.55}

/* artifacts on the results screen */
.artifact-card{position:relative;margin:22px 0;padding:26px 24px;background:#fff;
  border:1px solid #ece4f2;border-left:4px solid var(--mc,#ed7662);border-radius:0 14px 14px 0;
  box-shadow:0 12px 30px rgba(57,35,77,.07);text-align:left}
.six-words{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin:0}
.six-words span{font:600 clamp(19px,3vw,26px) 'Fraunces',Georgia,serif;color:#39234d}
.six-words span:nth-child(even){color:var(--mc,#b8558f)}
.forecast-line{padding:11px 0;border-bottom:1px solid #f2ecf6}
.forecast-line:last-child{border-bottom:0}
.forecast-line span{display:block;font:600 11.5px 'DM Sans',sans-serif;color:#9a8ea4;margin-bottom:3px}
.forecast-line strong{font:400 16px/1.5 'Fraunces',Georgia,serif;color:#39234d}

@media(max-width:640px){
  .word-row{grid-template-columns:repeat(3,1fr)}
  .timeline{grid-template-columns:1fr}
  .curve-day{grid-template-columns:38px 1fr 32px;gap:8px}
}

/* studio row on the overall fingerprint page */
.studio-heading{font:600 26px 'Fraunces',serif;margin:38px 0 3px;color:#39234d}
.studio-sub{margin:0 0 16px;font-size:14px;color:#8a7b95}
.studio-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));grid-auto-rows:1fr;gap:16px;align-items:stretch}
.con-artifact{padding:4px 2px}
.con-six{display:flex;flex-wrap:wrap;gap:6px;margin:0;justify-content:center}
.con-six span{font:600 17px 'Fraunces',Georgia,serif;color:#39234d}
.con-six span:nth-child(even){color:var(--mc,#b8558f)}
.con-line{padding:8px 0;border-bottom:1px solid #f2ecf6}
.con-line:last-child{border-bottom:0}
.con-line span{display:block;font:600 10px 'DM Sans',sans-serif;color:#9a8ea4;margin-bottom:2px}
.con-line strong{font:400 13.5px/1.45 'Fraunces',Georgia,serif;color:#39234d}

/* --- check-in hub cards -----------------------------------------------------
   Was a centred vertical stack with tiny type and a bare ↻ glyph nobody could
   read. Now a row: icon left, title and description right at a legible size,
   actions on the end. Completed cards go green rather than tinting to the
   module's own colour, so "done" reads at a glance across the whole list. */
.module-grid{display:grid;grid-template-columns:1fr;gap:10px;margin-top:26px}
.module-card{display:flex;align-items:center;gap:18px;text-align:left;
  padding:16px 18px;border:1.5px solid #e6dded;border-radius:13px;background:#fff;
  transition:transform .18s,box-shadow .18s,border-color .18s,background .18s}
.module-card:hover{transform:translateY(-2px);box-shadow:0 12px 26px rgba(57,35,77,.09)}
.module-card .module-icon{width:62px;height:62px;flex:none;display:grid;place-items:center;
  font-size:30px;color:var(--mc)}
.mc-body{flex:1;min-width:0}
.module-card strong{display:block;font:600 20px/1.2 'Fraunces',Georgia,serif;color:#39234d}
.module-card small{display:block;margin-top:3px;font-size:14px;line-height:1.45;color:#6b5f76}
.module-actions{display:flex;align-items:center;gap:9px;flex:none;flex-wrap:wrap;justify-content:flex-end}
.mc-done{font:700 11px 'DM Sans',sans-serif;letter-spacing:.05em;text-transform:uppercase;color:#2f7d4f}
.mc-go{border:0;border-radius:9px;padding:12px 17px;background:#402c68;color:#fff;
  font:700 13px 'DM Sans',sans-serif;cursor:pointer;white-space:nowrap;transition:background .15s}
.mc-go:hover{background:#31215a}
.mc-redo{border:1.5px solid #2f7d4f;border-radius:9px;padding:11px 16px;background:#fff;
  color:#2f7d4f;font:700 13px 'DM Sans',sans-serif;cursor:pointer;white-space:nowrap;transition:.15s}
.mc-redo:hover{background:#2f7d4f;color:#fff}
/* Completed = green, regardless of the module's own hue. */
.module-card.done{border-color:#a8d6ba;background:linear-gradient(180deg,#f4fbf6 0%,#ffffff 70%)}
.module-card.done .mc-go{background:#2f7d4f}
.module-card.done .mc-go:hover{background:#24623d}
@media(min-width:760px){.module-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){
  /* The actions row goes full-width here, which only works if the card may wrap. */
  .module-card{gap:13px;padding:13px 14px;flex-wrap:wrap}
  .mc-body{flex:1 1 130px}
  .module-card .module-icon{width:48px;height:48px;font-size:24px}
  .module-card strong{font-size:17px}
  .module-card small{font-size:13px}
  .module-actions{width:100%;justify-content:flex-start}
}

/* --- readable chart text ---------------------------------------------------
   SVG text scales with the drawing, so a 10px label inside a 460-unit viewBox
   rendered into a 286px card came out at 6px on screen. Sizes are now CSS
   variables that fitText() in fingerprint-viz.js sets from each chart's MEASURED
   scale, so a label lands at the same physical size whatever the card width. */

/* --- constellation legend ---
   The four surrounding radars are ~286px wide. "Thoughtful gestures" at a
   readable 13px is ~120px on its own, so two side labels plus the shape cannot
   fit — the names belong under the chart, at real text size, not inside it. */
.con-legend{display:grid;grid-template-columns:1fr 1fr;gap:3px 12px;margin:10px 0 0;
  padding-top:10px;border-top:1px solid #f0eaf4}
.con-card.core .con-legend{grid-template-columns:repeat(3,1fr)}
.con-legend div{display:flex;align-items:baseline;gap:6px;min-width:0;font-size:12px;line-height:1.35}
/* Wrap rather than ellipsize: "Thoughtful gestures" truncated to "Thoughtful gestur…" is
   exactly the unreadable-label problem this legend exists to solve. */
.con-legend span{flex:1;min-width:0;color:#6b5f76;overflow-wrap:break-word}
.con-legend b{flex:none;font:700 12.5px 'DM Sans',sans-serif;color:#39234d;
  font-variant-numeric:tabular-nums}
.con-legend i{flex:none;width:7px;height:7px;border-radius:2px;background:var(--mc);opacity:.85}
@media(max-width:560px){
  .con-legend,.con-card.core .con-legend{grid-template-columns:1fr}
  .con-legend div{font-size:13px}
}

/* --- the wall radar --------------------------------------------------------
   Names and values are one <text> per wall, so a single font-size variable
   drives both: the value tspan is sized in em, which keeps the pair locked
   together at whatever size fitText computes. */
.fp-wall-label{font-weight:600;font-family:'DM Sans',sans-serif;
  font-size:var(--fp-wall,15px);fill:#39234d}
.fp-wall-val{font-size:1.72em;font-weight:700;font-variant-numeric:tabular-nums}

/* Carbonation. Held still until the pointer is over the chart — a page of seven charts all
   fizzing at once is noise, and constant animation on a page someone is reading is worse than
   none. Each bubble carries its own duration and delay so they never march in step. */
.fp-wall .fp-bub circle,.fp-wall .fp-fizz circle{
  animation:fp-rise var(--d,4s) linear var(--t,0s) infinite;
  animation-play-state:paused;opacity:0}
.fp-wall:hover .fp-bub circle,.fp-wall:hover .fp-fizz circle,
.fp-wall:focus-visible .fp-bub circle,.fp-wall:focus-visible .fp-fizz circle{
  animation-play-state:running}
@keyframes fp-rise{
  0%{transform:translateY(0);opacity:0}
  14%{opacity:1}
  78%{opacity:.85}
  100%{transform:translateY(calc(var(--rise,40px) * -1));opacity:0}
}
/* At rest the bubbles are simply there, unmoving — the still frame still reads as a drink. */
.fp-wall .fp-bub circle{opacity:.62}
.fp-wall .fp-fizz circle{opacity:.5}
.fp-wall:hover .fp-bub circle,.fp-wall:hover .fp-fizz circle{opacity:0}
@media(prefers-reduced-motion:reduce){
  .fp-wall .fp-bub circle,.fp-wall .fp-fizz circle{animation:none;opacity:.55}
  .fp-wall:hover .fp-bub circle,.fp-wall:hover .fp-fizz circle{opacity:.55}
}

/* --- shimmer ---------------------------------------------------------------
   A shine sweeps each card every so often, staggered by position so they never
   flash in unison — a row of six cards catching the light at the same instant
   reads as a glitch rather than a gleam. The sweep is a pseudo-element above
   the card content but below nothing interactive (pointer-events:none), and it
   is off entirely for reduced-motion. */
.con-card{position:relative;overflow:hidden;isolation:isolate}
.con-card:after{content:'';position:absolute;inset:-40% -60%;z-index:2;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.72) 48%,
    rgba(255,248,245,.9) 51%,rgba(255,255,255,.72) 54%,transparent 64%);
  transform:translateX(-120%);
  animation:con-shine 9s cubic-bezier(.3,.1,.3,1) infinite}
.con-card:nth-child(2):after{animation-delay:1.5s}
.con-card:nth-child(3):after{animation-delay:3s}
.con-card:nth-child(4):after{animation-delay:4.5s}
.con-card:nth-child(5):after{animation-delay:6s}
.con-card:nth-child(6):after{animation-delay:7.5s}
@keyframes con-shine{
  0%{transform:translateX(-120%)}
  /* the sweep itself is quick; the rest of the cycle is the wait between */
  14%{transform:translateX(120%)}
  100%{transform:translateX(120%)}
}
@media(prefers-reduced-motion:reduce){.con-card:after{animation:none;display:none}}

/* --- the scanner ------------------------------------------------------------
   A beam sweeps the print and each sector lights as it passes, so the chart
   looks like it is being READ rather than merely displayed. The sweep period and
   every sector's delay come from one number in fingerprint-viz.js — drift them
   apart and sectors start flashing at nothing.

   The ridges keep their own colour throughout; the beam only changes brightness,
   so nothing about the data is ever conveyed by the animation alone. */
.fp-scan .fp-beam{animation:fp-sweep var(--sweep,8s) linear infinite;
  transform-origin:200px 200px;transform-box:view-box}
.fp-scan .fp-wake{animation:fp-wake var(--sweep,8s) linear var(--at,0s) infinite}
.fp-scan .fp-ping{animation:fp-ping var(--sweep,8s) ease-out infinite}
@keyframes fp-sweep{to{transform:rotate(360deg)}}
@keyframes fp-wake{
  0%{opacity:.62}
  4%{opacity:1}
  22%{opacity:.62}
  100%{opacity:.62}
}
@keyframes fp-ping{
  0%{r:34;opacity:.45}
  70%,100%{r:172;opacity:0}
}
@media(prefers-reduced-motion:reduce){
  /* Still, and fully lit — the frozen frame has to be the complete picture. */
  .fp-scan .fp-beam,.fp-scan .fp-ping{display:none}
  .fp-scan .fp-wake{animation:none;opacity:1}
}
