/* CACHET odds board (#odds), 2026-09-28. Loaded last on index and machine.
   A dark bento of neon instruments drawn by js/snag-lab.js from js/snag-market.js output.
   One ruled panel split by hairlines (the 1px grid gap shows the line colour), no nested
   cards. The violet to amber seal gradient sits on strokes only; numbers stay ink.
   Motion is transform, opacity and stroke-dashoffset on the expo ease, static under
   reduced motion. Adapted from 21st.dev references: the radar chart with glow (neon arc
   dials), the bento grid (a hero cell spanning two rows beside smaller cells) and the
   animated bar chart (bars that rise in, the current one lit). Spacing is the 4pt scale. */

/* ---------- The board ---------- */
.odds-board{grid-column:1/-1;display:grid;grid-template-columns:minmax(0,1fr);gap:1px;min-width:0;border:1px solid var(--line);border-radius:var(--radius);background:var(--line);overflow:hidden}
.odds-cell{position:relative;display:grid;align-content:start;gap:var(--space-16);min-width:0;padding:var(--space-24);background:var(--ground)}
.odds-board .odds-group{border-top:0;padding:var(--space-24)}
.odds-cell-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--space-4) var(--space-12);min-width:0}
.odds-board .odds-cell-head h3{display:block;margin:0;font:500 var(--fs-label)/1.4 var(--font-mono);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-soft)}
.odds-cell-meta{font:400 var(--fs-label)/1.4 var(--font-mono);color:var(--mute);white-space:nowrap}

/* ---------- Hero: the piece, its 1 in N, the arch and the rank band ---------- */
.odds-hero-body{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-24);align-items:center;min-width:0}
.odds-hero-piece{justify-self:center;width:min(100%,200px)}
.odds-hero-piece .piece-card{width:100%}
.odds-hero-blank{display:block;width:100%;height:auto}
.odds-hero-blank rect{fill:none;stroke:var(--line);stroke-width:1}
.odds-hero-blank path{fill:none;stroke:var(--line);stroke-width:3;stroke-linecap:round}
.odds-hero-vis{min-width:0}
.odds-hero .odds-vis{padding-top:0}
.odds-idle{display:grid;gap:var(--space-8);padding:var(--space-24) 0;border-block:1px dashed var(--line)}
.odds-idle p{margin:0}
.odds-idle-lead{font:600 var(--fs-h3)/1.3 var(--font-display);color:var(--ink)}
.odds-idle-copy{max-width:40ch;font:400 var(--fs-body)/1.55 var(--font-body);color:var(--ink-soft)}

/* ---------- Most common to rarest: one log line ---------- */
.odds-span{position:relative;height:56px;margin-top:var(--space-8);container-type:inline-size}
.odds-span-line{position:absolute;left:0;right:0;top:20px;height:2px;border-radius:2px;background:var(--seal-gradient);box-shadow:0 0 10px color-mix(in srgb,var(--seal-2) 45%,transparent);transform-origin:left center;animation:odds-grow 1100ms var(--ease) backwards}
.odds-span-tick{position:absolute;left:0;top:14px;width:1px;height:14px;background:color-mix(in srgb,var(--mute) 55%,transparent);transform:translateX(calc(var(--pos) * 100cqw))}
.odds-span-tick span{position:absolute;left:0;top:18px;transform:translateX(-50%);font:400 var(--fs-label)/1 var(--font-mono);color:var(--mute);white-space:nowrap}
.odds-span-mark{position:absolute;left:-6px;top:15px;width:12px;height:12px;border-radius:50%;background:var(--seal-4);box-shadow:0 0 12px var(--seal-4);opacity:0;transform:translateX(calc(var(--pos) * 100cqw));transition:transform 900ms var(--ease),opacity 480ms var(--ease)}
.odds-span-mark span{position:absolute;left:50%;bottom:calc(100% + var(--space-4));transform:translateX(-50%);font:600 var(--fs-label)/1 var(--font-mono);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--accent-deep)}
.odds-span.has-mark .odds-span-mark{opacity:1}
.odds-ends-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-16)}
.odds-end{display:grid;align-content:start;gap:var(--space-4);min-width:0}
.odds-end.is-rarest{justify-items:end;text-align:right}
.odds-end-kicker{font:500 var(--fs-label)/1.4 var(--font-mono);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--mute)}
.odds-end-value{font:500 var(--fs-body)/1.2 var(--font-mono);color:var(--ink-soft);white-space:nowrap;font-variant-numeric:tabular-nums}
.odds-end-value strong{font:600 var(--fs-h3)/1.1 var(--font-mono);letter-spacing:-.02em;color:var(--ink)}
.odds-end-mix{max-width:28ch;font:400 var(--fs-label)/1.5 var(--font-body);color:var(--ink-soft)}
.odds-span-you{margin:0;padding-top:var(--space-12);border-top:1px solid var(--line);font:400 var(--fs-label)/1.5 var(--font-mono);color:var(--ink-soft)}

/* ---------- Every mix, by rank: mirrored neon histogram ---------- */
.odds-histo-plot{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--space-8);min-width:0;container-type:inline-size}
.odds-histo-col{display:grid;grid-template-rows:auto 88px 56px auto auto;justify-items:center;min-width:0}
.odds-histo-n,.odds-histo-s{font:500 var(--fs-label)/1.4 var(--font-mono);color:var(--ink-soft);font-variant-numeric:tabular-nums;white-space:nowrap}
.odds-histo-n{padding-bottom:var(--space-4)}
.odds-histo-s{padding-top:var(--space-4);color:var(--mute)}
.odds-histo-bar{position:relative;display:block;width:100%;height:100%}
.odds-histo-bar.is-mixes{border-bottom:1px solid var(--line)}
.odds-histo-bar i{position:absolute;left:50%;width:8px;margin-left:-4px;border-radius:4px;opacity:.5;transition:opacity 480ms var(--ease)}
.odds-histo-bar.is-mixes i{bottom:0;height:max(2px,calc(var(--h) * 100%));background:var(--arc);transform-origin:bottom;animation:odds-rise 900ms var(--ease) backwards;animation-delay:calc(var(--i,0) * 60ms)}
.odds-histo-bar.is-share i{top:4px;height:max(4px,calc(var(--s) * (100% - 4px)));box-shadow:inset 0 0 0 1.5px var(--arc);transform-origin:top;animation:odds-rise 900ms var(--ease) backwards;animation-delay:calc(var(--i,0) * 60ms + 120ms)}
.odds-board:not(.has-pick) .odds-histo-bar i{opacity:.8}
.odds-histo-col.is-current .odds-histo-bar i{opacity:1}
.odds-histo-col.is-current .odds-histo-bar.is-mixes i{box-shadow:0 0 12px var(--arc)}
.odds-histo-col.is-current .odds-histo-bar.is-share i{box-shadow:inset 0 0 0 1.5px var(--arc),0 0 12px var(--arc)}
.odds-histo-name{padding-top:var(--space-4);font:500 var(--fs-label)/1.3 var(--font-body);color:var(--mute);white-space:nowrap}
.odds-histo-col.is-current .odds-histo-name,.odds-histo-col.is-current .odds-histo-n{color:var(--ink)}
.odds-histo-key{display:flex;flex-wrap:wrap;gap:var(--space-4) var(--space-16);margin:0;font:400 var(--fs-label)/1.4 var(--font-mono);color:var(--mute)}
.odds-histo-key span{display:inline-flex;align-items:center;gap:var(--space-8)}
.odds-histo-key span::before{content:"";width:8px;height:12px;border-radius:4px}
.odds-key-mixes::before{background:var(--seal-2)}
.odds-key-share::before{box-shadow:inset 0 0 0 1.5px var(--seal-2)}
/* Narrow plots drop every second rank name a line so no two labels touch. */
@container (max-width:340px){.odds-histo-col:nth-child(even) .odds-histo-name{padding-top:calc(var(--space-4) + 1.3em)}}

/* ---------- Trait dials: arc length is the option's weight ---------- */
.odds-dial{position:relative;width:min(100%,208px);aspect-ratio:1;margin:0 auto}
.odds-dial-svg{display:block;width:100%;height:100%;overflow:visible}
.odds-dial-ticks{fill:none;stroke:var(--mute);stroke-width:1;opacity:.35}
.odds-dial-inner{fill:none;stroke:var(--line);stroke-width:1;stroke-dasharray:1 5}
.odds-arc{fill:none;stroke:var(--arc);stroke-width:12;stroke-linecap:butt;stroke-dasharray:100 100;opacity:.72;outline:none;cursor:pointer;transition:opacity 320ms var(--ease);animation:odds-arc-draw 1100ms var(--ease) backwards;animation-delay:calc(var(--i,0) * 70ms)}
.odds-board.has-pick .odds-arc{opacity:.3}
.odds-board .odds-arc.is-lit{opacity:1;stroke-width:18;filter:drop-shadow(0 0 6px var(--arc))}
.odds-group.is-probing .odds-arc{opacity:.22}
.odds-group.is-probing .odds-arc.is-lit{opacity:.55}
.odds-group.is-probing .odds-arc.is-hot{opacity:1}
.odds-board .odds-arc:focus-visible{opacity:1;stroke-width:18;filter:drop-shadow(0 0 1.5px var(--ink)) drop-shadow(0 0 8px var(--arc))}
.odds-dial-pin{transform-box:view-box;transform-origin:100px 100px;transform:rotate(var(--rot,0deg));opacity:0;transition:transform 900ms var(--ease),opacity 320ms var(--ease)}
.odds-dial-pin.is-on{opacity:1}
.odds-dial-pin circle{fill:var(--seal-4);filter:drop-shadow(0 0 5px var(--seal-4))}
.odds-dial-core{position:absolute;inset:23%;display:grid;place-content:center;justify-items:center;gap:2px;text-align:center;pointer-events:none}
.odds-dial-kicker{font:500 var(--fs-label)/1.3 var(--font-mono);letter-spacing:.04em;text-transform:uppercase;color:var(--mute)}
.odds-dial-name{max-width:100%;font:600 var(--fs-body)/1.2 var(--font-display);color:var(--ink);text-wrap:balance;overflow-wrap:anywhere}
.odds-dial-pct{font:600 var(--fs-h3)/1.1 var(--font-mono);letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums}
.odds-board.has-pick .odds-dial-pct{color:var(--accent-deep)}
/* The reading for the arc under the pointer or focus. */
.odds-tip{--tx:-50%;--ty:calc(-100% - 12px);position:absolute;z-index:3;display:flex;align-items:baseline;gap:var(--space-8);padding:var(--space-4) var(--space-8);border:1px solid var(--line);border-radius:var(--radius);background:var(--band);box-shadow:0 8px 24px rgb(0 0 0 / .5);font:500 var(--fs-label)/1.4 var(--font-mono);color:var(--ink);white-space:nowrap;pointer-events:none;transform:translate(var(--tx),var(--ty));animation:odds-tip-in 240ms var(--ease)}
.odds-tip[hidden]{display:none}
.odds-tip b{font-weight:600}
.odds-tip span{color:var(--accent-deep)}
.odds-tip[data-side=start]{--tx:-8px}
.odds-tip[data-side=end]{--tx:calc(-100% + 8px)}
.odds-tip[data-v=below]{--ty:12px}
/* The key under each dial: a short stroke in the arc's own colour, the name, the weight. */
.odds-board .odds-bars{display:grid;grid-template-columns:minmax(0,1fr);gap:2px;margin:0}
.odds-board .odds-option{display:grid;grid-template-columns:12px minmax(0,1fr) auto;align-items:center;gap:var(--space-8);min-height:24px;font:400 var(--fs-label)/1.3 var(--font-body);color:var(--mute)}
.odds-board .odds-column{grid-column:auto;grid-row:auto;width:12px;height:3px;border-radius:2px;background:var(--arc);overflow:visible;opacity:.75}
.odds-board .odds-column i{display:none}
.odds-board .odds-label{display:block;min-width:0;gap:0}
.odds-board .odds-option strong{grid-column:auto;grid-row:auto;font:500 var(--fs-label)/1.3 var(--font-mono);text-align:right;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.odds-board .odds-option.is-picked,.odds-board .odds-option.is-hot{color:var(--ink)}
.odds-board .odds-option.is-picked strong{color:var(--accent-deep)}
.odds-board .odds-option.is-picked .odds-column,.odds-board .odds-option.is-hot .odds-column{opacity:1;box-shadow:0 0 6px var(--arc)}

@keyframes odds-arc-draw{from{stroke-dashoffset:100}}
@keyframes odds-rise{from{transform:scaleY(0)}}
@keyframes odds-grow{from{transform:scaleX(0)}}
@keyframes odds-tip-in{from{opacity:0}}

/* ---------- Layout ---------- */
/* Phones: one column; each dial sits beside its key. */
@media(max-width:639px){
  .odds-cell,.odds-board .odds-group{padding:var(--space-16)}
  .odds-board .odds-group{grid-template-columns:minmax(0,136px) minmax(0,1fr);align-items:center;gap:var(--space-16)}
  .odds-board .odds-group .odds-cell-head{grid-column:1/-1}
  .odds-hero-piece{width:min(100%,176px)}
}
@media(max-width:479px){
  .odds-ends-grid{grid-template-columns:minmax(0,1fr)}
  .odds-end.is-rarest{justify-items:start;text-align:left}
}
@media(min-width:640px){
  .odds-board{grid-template-columns:repeat(2,minmax(0,1fr))}
  .odds-hero,.odds-extremes,.odds-histo,.odds-board .odds-group:last-child{grid-column:1/-1}
  .odds-hero-body{grid-template-columns:minmax(0,184px) minmax(0,1fr);gap:var(--space-32)}
  .odds-hero-piece{width:100%}
}
/* Desktop bento: the hero spans two rows beside the log line and the histogram, then five dials. */
@media(min-width:1024px){
  .odds-board{grid-template-columns:repeat(10,minmax(0,1fr))}
  .odds-hero{grid-column:span 6;grid-row:span 2;padding:var(--space-32)}
  .odds-extremes,.odds-histo{grid-column:span 4}
  .odds-board .odds-group,.odds-board .odds-group:last-child{grid-column:span 2}
}
@media(min-width:1280px){.odds-hero-body{grid-template-columns:minmax(0,208px) minmax(0,1fr)}}

@media(prefers-reduced-motion:reduce){
  .odds-arc,.odds-dial-pin,.odds-span-line,.odds-span-mark,.odds-histo-bar i,.odds-tip{animation:none;transition:none}
}
