/* THE SETTLE — deep ink + amber, parchment cards, brass scales.
   Fit law: the whole daily flow lives in one 100dvh screen at every
   size; all vertical sizing is fluid (clamp + dvh) so nothing clips
   and nothing scrolls in the game. Results are designed to fit too;
   overflow-y:auto there is a safety net, not the plan. */
:root{
  --ink:#0e1015; --ink2:#12151d; --panel:#171b24; --panel-edge:#262c38;
  --parch:#f4ead3; --parch2:#e9dcba; --on-parch:#211c10;
  --amber:#e9a13b; --brass:#b9822e; --paper:#f2ede1; --muted:#9aa3b2;
  --good:#57b368; --warm:#e07b39; --hot:#e05d44;
  --disp:"Palatino","Palatino Linotype","Book Antiqua",Georgia,serif;
  --ui:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
.visually-hidden{position:absolute !important; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}
html,body{height:100%}
body{
  margin:0; background:var(--ink); color:var(--paper); font-family:var(--ui);
  display:flex; justify-content:center;
  background-image:radial-gradient(ellipse 90% 55% at 50% -8%, #1d2331 0%, var(--ink) 60%);
}
.hidden{display:none !important}
button{font-family:inherit}
:focus-visible{outline:2px solid var(--amber); outline-offset:2px}

.app{
  width:min(100%,460px); height:100vh; height:100dvh;
  display:flex; flex-direction:column;
  padding:max(10px, env(safe-area-inset-top)) clamp(12px,4vw,20px) max(8px, env(safe-area-inset-bottom));
  gap:clamp(6px,1.1dvh,12px);
}
@media (min-width:700px) and (min-height:700px){
  .app{border-left:1px solid #1e232f; border-right:1px solid #1e232f; box-shadow:0 0 60px rgba(0,0,0,.5); background:rgba(255,255,255,.012)}
}

/* ---------------------------------------------------------- masthead */
.mast{display:flex; align-items:center; justify-content:space-between; gap:10px; flex:0 0 auto}
.brand{display:flex; align-items:center; gap:10px; min-width:0}
.scales{height:clamp(30px,5dvh,44px); width:auto; color:var(--amber); flex:0 0 auto}
.brand-text h1{
  margin:0; font-family:var(--disp); font-weight:700; letter-spacing:.04em;
  font-size:clamp(19px,3.2dvh,28px); line-height:1; white-space:nowrap;
}
.brand-text p{margin:2px 0 0; font-size:clamp(10px,1.5dvh,12px); color:var(--muted); white-space:nowrap}
.mast-actions{display:flex; align-items:center; gap:6px; flex:0 0 auto}
.day-chip{
  font-family:var(--disp); font-weight:700; color:var(--ink);
  background:linear-gradient(180deg,var(--amber),var(--brass));
  border-radius:999px; padding:3px 10px; font-size:clamp(12px,1.9dvh,14px);
}
.icon-btn{
  /* QA3 F9: hit area ≥44px at every size; the visual glyph stays small
     (padding keeps the circle the same apparent size while the target
     grows — the button itself is the target, so grow the button and
     let the border ride a smaller inner disc via background-clip). */
  width:44px; height:44px; border-radius:50%; border:1px solid var(--panel-edge);
  background:var(--panel); color:var(--paper); font-size:16px; cursor:pointer; line-height:1;
  display:grid; place-items:center; flex:0 0 auto;
}
.icon-btn:active{transform:scale(.94)}

/* ------------------------------------------------------------- screens */
.screen{flex:1 1 auto; min-height:0; display:flex; flex-direction:column; gap:clamp(6px,1.1dvh,12px)}
.cat-row{display:flex; align-items:center; gap:8px; flex:0 0 auto; min-height:0}
.cat-emoji{font-size:clamp(18px,3dvh,24px)}
.cat-name{margin:0; font-family:var(--disp); font-size:clamp(16px,2.6dvh,21px); font-weight:700; letter-spacing:.01em}
.badge{
  margin-left:auto; font-size:11px; font-weight:700; letter-spacing:.08em;
  color:var(--amber); border:1px solid var(--brass); border-radius:999px; padding:2px 8px;
}

/* hero card — the item on the scales right now */
.hero{
  flex:0 0 auto; display:flex; align-items:center; gap:clamp(10px,3vw,16px);
  background:linear-gradient(160deg,var(--parch),var(--parch2));
  color:var(--on-parch); border-radius:16px;
  padding:clamp(8px,1.5dvh,16px) clamp(12px,4vw,18px);
  box-shadow:0 10px 26px rgba(0,0,0,.42), inset 0 1px 0 rgba(255,255,255,.55);
}
.hero-emoji{font-size:clamp(42px,10.5dvh,80px); line-height:1; filter:drop-shadow(0 3px 4px rgba(60,40,0,.25))}
.hero-text{min-width:0}
.hero-name{font-family:var(--disp); font-weight:700; font-size:clamp(20px,3.8dvh,30px); line-height:1.05}
.hero-sub{font-size:clamp(11px,1.7dvh,13px); color:#6b5c33; margin-top:3px}
.hero.dealt{animation:heroIn .38s cubic-bezier(.2,.9,.25,1.2)}
@keyframes heroIn{from{opacity:0; transform:translateY(12px) rotate(.8deg) scale(.97)} to{opacity:1; transform:none}}

/* rank slots */
.slots{list-style:none; margin:0; padding:0; flex:1 1 auto; min-height:0; display:flex; flex-direction:column; gap:clamp(5px,1dvh,9px)}
/* QA3 F10: a slot row never shrinks below a usable target — at very
   short viewports the column gives the hero room instead. */
.slots li{flex:1 1 0; min-height:44px; max-height:120px; display:flex}
/* QA3 F13: on tall viewports the rows stop growing at a composed
   card height instead of ballooning into empty slabs; leftover
   space parks below the board. */
.slots{align-content:flex-start}
.slot.skeleton{cursor:default; pointer-events:none; opacity:.55}
.slot.skeleton .slot-name{color:var(--muted); font-style:italic; font-weight:400}
.slots.loading .slot.skeleton{animation:skelPulse 1.1s ease-in-out infinite alternate}
@keyframes skelPulse{from{opacity:.35} to{opacity:.6}}
.slot{
  flex:1; display:flex; align-items:center; gap:clamp(8px,2.5vw,14px);
  background:var(--panel); border:1px solid var(--panel-edge); border-radius:13px;
  color:var(--paper); padding:2px clamp(10px,3.5vw,16px); cursor:pointer; text-align:left;
  transition:transform .08s ease, background .15s ease;
}
.slot:active{transform:scale(.985)}
.slot-num{font-family:var(--disp); font-weight:700; color:var(--amber); font-size:clamp(16px,2.8dvh,22px); width:1.35em; text-align:center; flex:0 0 auto}
.slot-emoji{font-size:clamp(20px,4.2dvh,30px); line-height:1; flex:0 0 auto}
.slot-name{font-size:clamp(14px,2.3dvh,17px); font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.slot .slot-open{color:var(--muted); font-weight:400; font-style:italic; font-size:clamp(12px,2dvh,14px)}
.slot.filled{
  background:linear-gradient(160deg,var(--parch),var(--parch2)); color:var(--on-parch);
  border-color:#c9b078; cursor:default; box-shadow:0 4px 14px rgba(0,0,0,.35);
}
/* QA3 F7: the filled-slot rank numeral must clear 3:1 (large bold
   text) on the parchment gradient — --brass #b9822e measured 2.61:1.
   Filled slots get a deeper bronze (#8a5f1d, ≈4.06:1 worst stop,
   ≈4.47:1 best stop) scoped to this one surface; --brass elsewhere
   (day chip, button gradients, borders) is unchanged. */
.slot.filled .slot-num{color:#8a5f1d}
.slot.placed{animation:popIn .3s cubic-bezier(.2,.9,.3,1.4)}
@keyframes popIn{0%{transform:scale(.96)} 60%{transform:scale(1.015)} 100%{transform:scale(1)}}
.slot.shake{animation:shake .3s ease}
@keyframes shake{0%,100%{transform:none} 25%{transform:translateX(-4px)} 75%{transform:translateX(4px)}}
.hint{margin:0; text-align:center; font-size:clamp(11px,1.6dvh,12.5px); color:var(--muted); flex:0 0 auto}

/* ------------------------------------------------------------- results */
#screenResults{gap:clamp(5px,1dvh,10px); overflow-y:auto; scrollbar-width:thin}
.res-top{display:flex; align-items:center; gap:clamp(12px,4vw,20px); flex:0 0 auto}
.score-block{display:flex; align-items:baseline; gap:2px}
.score-num{font-family:var(--disp); font-weight:700; color:var(--amber); font-size:clamp(46px,9.5dvh,74px); line-height:.95}
.score-of{color:var(--muted); font-size:clamp(13px,2dvh,16px)}
.verdict-block{min-width:0}
.verdict{font-family:var(--disp); font-weight:700; font-size:clamp(18px,3.2dvh,25px); line-height:1.1}
.verdict-line{margin:3px 0 0; font-size:clamp(12px,1.9dvh,14px); color:var(--muted)}
.hottest{
  flex:0 0 auto; border:1px solid var(--brass); border-radius:12px;
  background:linear-gradient(160deg, rgba(233,161,59,.14), rgba(233,161,59,.05));
  padding:clamp(6px,1.2dvh,10px) 12px; font-size:clamp(12.5px,2dvh,14.5px);
}
.hottest strong{color:var(--amber)}
.res-table{flex:0 0 auto; border:1px solid var(--panel-edge); border-radius:13px; overflow:hidden}
.res-row{
  display:grid; grid-template-columns:2.1em minmax(0,1fr) auto auto; align-items:center;
  gap:8px; padding:clamp(4px,.9dvh,8px) 10px; background:var(--panel);
  font-size:clamp(13px,2.1dvh,15px); border-bottom:1px solid #20242f;
  animation:fadeUp .4s ease both;
}
.res-row:last-child{border-bottom:none}
.res-row.head{background:var(--ink2); color:var(--muted); font-size:clamp(10px,1.5dvh,11.5px); letter-spacing:.07em; text-transform:uppercase; animation:none}
.res-row .r-num{font-family:var(--disp); font-weight:700; color:var(--amber); text-align:center}
/* QA3 F6: results names wrap instead of ellipsis-truncating — at
   320px a name is always fully readable (rows grow, never hide). */
.res-row .r-item{white-space:normal; overflow-wrap:anywhere; font-weight:600; min-width:0}
.res-row .r-item .e{margin-right:6px}
.res-row .r-avg{color:var(--muted); font-variant-numeric:tabular-nums; white-space:nowrap}
.res-row .r-you{font-weight:700; white-space:nowrap; min-width:3.2em; text-align:right}
.r-you.exact{color:var(--good)} .r-you.near{color:var(--amber)} .r-you.far{color:var(--hot)}
@keyframes fadeUp{from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:none}}
/* pass #2: an always-visible notice banner on results (replaces the
   old settling-line swap for expiredPending / grace-cast notes — the
   "never counted" word must be impossible to miss, QA5 F11). */
.banner{
  flex:0 0 auto; border:1px solid var(--brass); border-radius:12px;
  background:linear-gradient(160deg, rgba(233,161,59,.16), rgba(233,161,59,.06));
  padding:clamp(6px,1.2dvh,10px) 12px; font-size:clamp(12.5px,2dvh,14.5px);
}
.meta-row{display:flex; flex-wrap:wrap; gap:6px; flex:0 0 auto}
.meta-chip{border:1px solid var(--panel-edge); background:var(--ink2); border-radius:999px; padding:3px 10px; font-size:clamp(11.5px,1.8dvh,13px); color:var(--paper)}
.meta-chip strong{color:var(--amber)}
.settling{margin:0; font-size:clamp(11px,1.7dvh,12.5px); color:var(--muted); font-style:italic; flex:0 0 auto}
.actions{display:flex; gap:8px; flex-wrap:wrap; flex:0 0 auto}
.btn{
  border-radius:999px; padding:clamp(8px,1.5dvh,11px) 18px; font-size:clamp(13.5px,2.1dvh,15px);
  font-weight:700; cursor:pointer; border:1px solid var(--panel-edge);
  background:var(--panel); color:var(--paper);
}
.btn:active{transform:scale(.97)}
.btn.primary{background:linear-gradient(180deg,var(--amber),var(--brass)); color:#221503; border-color:#8a5f1d}
.btn.wide{width:100%}
.countdown{margin:0; font-size:clamp(11px,1.7dvh,12.5px); color:var(--muted); flex:0 0 auto}
.countdown strong{color:var(--paper); font-variant-numeric:tabular-nums}

/* ---------------------------------------------------------------- foot */
.foot{
  flex:0 0 auto; display:flex; justify-content:space-between; gap:10px;
  font-size:clamp(10.5px,1.6dvh,12px); color:var(--muted);
  border-top:1px solid #1b1f29; padding-top:6px;
}

/* -------------------------------------------------------------- modals */
.modal-back{
  position:fixed; inset:0; background:rgba(4,6,10,.66); backdrop-filter:blur(2px);
  display:grid; place-items:center; padding:16px; z-index:40;
}
.modal{
  background:linear-gradient(165deg,var(--parch),var(--parch2)); color:var(--on-parch);
  border-radius:18px; max-width:min(94vw,430px); width:100%; max-height:88dvh; overflow-y:auto;
  padding:clamp(16px,3dvh,26px); box-shadow:0 24px 60px rgba(0,0,0,.55);
}
.modal h3{margin:0 0 10px; font-family:var(--disp); font-size:clamp(19px,3dvh,24px)}
.modal p{margin:0 0 10px; font-size:14.5px; line-height:1.45}
.modal .example{background:rgba(185,130,46,.14); border-radius:10px; padding:9px 11px}
.stats-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:8px; margin:6px 0 12px}
.stats-grid>div{background:rgba(255,255,255,.35); border:1px solid #c9b078; border-radius:12px; padding:9px 4px; text-align:center}
.stat-num{display:block; font-family:var(--disp); font-weight:700; font-size:24px}
.stat-lbl{font-size:11px; letter-spacing:.06em; text-transform:uppercase; color:#6b5c33}
.stats-note{font-size:13px; color:#6b5c33}

#confetti{position:fixed; inset:0; width:100%; height:100%; pointer-events:none; z-index:45}

/* --------------------------------------------------------- flash/toast */
.flash{
  position:fixed; inset:0; display:grid; place-items:center; z-index:50; pointer-events:none;
  background:rgba(6,8,12,.45);
}
.flash span{
  font-family:var(--disp); font-weight:700; letter-spacing:.05em; color:var(--amber);
  font-size:clamp(26px,6dvh,50px); background:var(--ink2); border:2px solid var(--brass);
  border-radius:16px; padding:.35em .7em; animation:stamp .55s cubic-bezier(.2,.9,.3,1.3) both;
  box-shadow:0 18px 50px rgba(0,0,0,.6);
}
@keyframes stamp{0%{opacity:0; transform:scale(1.6) rotate(-4deg)} 100%{opacity:1; transform:scale(1) rotate(-1.5deg)}}
.toast{
  position:fixed; left:50%; bottom:max(18px, env(safe-area-inset-bottom)); transform:translateX(-50%);
  background:var(--parch); color:var(--on-parch); font-weight:600; font-size:14px;
  border-radius:999px; padding:9px 18px; box-shadow:0 10px 30px rgba(0,0,0,.5); z-index:60;
}

/* ------------------------------------------------ narrow phone widths */
@media (max-width: 430px){
  .brand{gap:7px}
  .brand-text h1{font-size:19px}
  .scales{height:28px}
  .mast-actions{gap:5px}
  .day-chip{padding:2px 8px}
  .icon-btn{font-size:15px}
}

/* --------------------------------- very short + narrow (320x568 etc.) */
@media (max-width:360px) and (max-height:620px){
  /* QA3 F5 sibling: 320x568 practice-Beach Day results measured
     497 vs 482 (countdown clipped) — the same compact rhythm as the
     landscape tier, sized for portrait phones. */
  #screenResults{gap:4px}
  #screenResults .score-num{font-size:42px}
  #screenResults .verdict{font-size:17px}
  #screenResults .hottest{padding:5px 10px; font-size:12px}
  #screenResults .banner{padding:5px 10px; font-size:12px}
  #screenResults .res-row{padding:3px 8px; font-size:12.5px}
  #screenResults .meta-chip{padding:2px 8px; font-size:11px}
  #screenResults .btn{padding:7px 14px; font-size:13px}
  .hero{padding-top:6px; padding-bottom:6px}
  .hero-emoji{font-size:40px}
}

/* ------------------------------------------- short screens (landscape) */
@media (max-height:480px){
  .brand-text p{display:none}
  .scales{height:26px}
  .hero-emoji{font-size:clamp(34px,12dvh,52px)}
  .hero-name{font-size:clamp(17px,4.4dvh,24px)}
  .hint{display:none}
  .foot{display:none}
  .app{gap:5px; padding-top:max(6px, env(safe-area-inset-top)); padding-bottom:max(5px, env(safe-area-inset-bottom))}
  /* QA3 F5: compact results tier — at landscape heights the results
     screen tightens every rhythm so the full flow incl. Share fits
     one screen with no scroll (844x390 measured 381 vs 340 before). */
  #screenResults{gap:3px}
  #screenResults .score-num{font-size:clamp(34px,11dvh,48px)}
  #screenResults .verdict{font-size:clamp(15px,4.6dvh,19px)}
  #screenResults .verdict-line{font-size:11.5px; margin-top:1px}
  #screenResults .hottest{padding:4px 10px; font-size:12px}
  #screenResults .banner{padding:4px 10px; font-size:12px}
  #screenResults .res-row{padding:2px 8px; font-size:12.5px}
  #screenResults .res-row.head{font-size:9.5px}
  #screenResults .meta-chip{padding:2px 8px; font-size:11px}
  #screenResults .settling{font-size:11px}
  #screenResults .btn{padding:6px 14px; font-size:13px}
  #screenResults .countdown{font-size:11px}
  /* QA3 F11: the help modal's content scrolls inside the modal, so
     its closing button is always reachable at short heights. */
  .modal{max-height:calc(100dvh - 24px)}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001s !important; transition-duration:.001s !important}
}
