:root {
  --bg: #14181d;
  --panel: #1e242b;
  --panel-2: #262d36;
  --ink: #e8ebef;
  --muted: #9aa5b1;
  --accent: #e0a91b;
  --good: #3f9b46;
  --bad: #cc3333;
  --line: #333c46;
  --rock: #6b6157;
  --rock-2: #574e45;
  --crack-dark: #0b0d10;
  /* Shared fractal-noise grain (inline SVG); alpha channel varies, so it works
     both as a soft-light texture layer and as a gritty alpha mask. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; }

/* The [hidden] attribute must always win, even over rules that set display
   (e.g. .verdict uses display:flex) — otherwise hidden elements stay visible. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---------- top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1rem;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar h1 {
  font-size: 1.15rem;
  margin: 0;
  letter-spacing: 0.5px;
}
/* Full title on wide screens, "C&R" in the mobile menu bar. */
.title-short { display: none; }
@media (max-width: 560px) {
  .title-full { display: none; }
  .title-short { display: inline; }
}
.tabs { display: flex; gap: 0.25rem; margin-left: auto; }
.tab {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  padding: 0.4rem 0.8rem;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.95rem;
}
.tab:hover { color: var(--ink); }
.tab.active { background: var(--panel-2); color: var(--ink); border-color: var(--line); }
/* Icon tabs: keep glyph and inline-SVG the same visual size and centred. */
.tab { display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
.tab svg { width: 1.2em; height: 1.2em; display: block; }
/* Cam icon (Noun Project) inlined; larger box since the source art has margins. */
.tab .tab-cam { width: 1.5em; height: 1.5em; }

.diff-select {
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 0.35rem 0.5rem; font-size: 0.9rem; cursor: pointer;
}
/* full-width red banner shown at the top whenever the screen is uncalibrated */
.cal-banner {
  background: var(--bad); color: #fff;
  text-align: center; padding: 0.6rem 1rem;
  font-size: 0.9rem; font-weight: 600;
}
.cal-banner a { color: #fff; text-decoration: underline; }

/* ---------- collapsible header ---------- */
.collapse-btn {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--muted);
  width: 30px; height: 30px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.7rem;
  line-height: 1;
}
.collapse-btn:hover { color: var(--ink); }
.expand-btn {
  display: none;
  position: fixed;
  top: 8px; left: 10px;
  z-index: 20;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--muted);
  padding: 0.35rem 0.6rem;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.8rem;
  box-shadow: 0 3px 10px rgba(0,0,0,0.4);
}
.expand-btn:hover { color: var(--ink); }
.header-collapsed .topbar { display: none; }
.header-collapsed .expand-btn { display: block; }
/* Keep content clear of the fixed expand button when the header is hidden. */
.header-collapsed main { padding-top: 3.2rem; }

/* ---------- layout ---------- */
main { max-width: 900px; margin: 0 auto; padding: 1.25rem 1rem 4rem; }
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1.25rem 1.4rem;
}
h2 { margin-top: 0; }
.lede { color: var(--muted); line-height: 1.5; max-width: 60ch; }
.intro-steps { color: var(--ink); line-height: 1.6; max-width: 60ch; padding-left: 1.2rem; margin: 1rem 0; }
.intro-steps li { margin: 0.5rem 0; }
.intro-steps strong { color: var(--accent); }
.hint { color: var(--muted); font-size: 0.9rem; line-height: 1.45; max-width: 60ch; }
.muted { color: var(--muted); }

/* ---------- calibration ---------- */
.seg {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  margin: 0.5rem 0 1rem;
}
.seg-btn {
  background: var(--panel-2);
  border: none;
  color: var(--muted);
  padding: 0.5rem 1rem;
  cursor: pointer;
}
.seg-btn.active { background: var(--accent); color: #1a1a1a; font-weight: 600; }

.card-stage, .ruler-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem 0;
  min-height: 160px;
}
.card-stage { min-height: 0; } /* portrait card can be tall; let it size itself */
/* On phones the true-size card can be wider than the padded panel; let the stage
   use the full viewport so both card edges stay visible and it can't overflow into
   growing only vertically. (A real 54 mm card is always narrower than any phone.) */
@media (max-width: 560px) {
  .card-stage {
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    padding: 1rem 8px;
    overflow: hidden;
  }
}
/* Chevron nudge buttons — a larger-target alternative to the slider, which the
   physical card can cover. */
.card-nudge { display: flex; justify-content: space-between; gap: 0.6rem; margin: 0.2rem 0 0.4rem; }
.nudge-btn {
  flex: 1;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 9px;
  padding: 0.6rem 0.8rem; font-size: 1rem; font-weight: 600; cursor: pointer;
  user-select: none; -webkit-user-select: none; touch-action: manipulation;
}
.nudge-btn:active { background: var(--accent); color: #1a1a1a; border-color: var(--accent); }
.credit-card {
  background: linear-gradient(135deg, #3a4653, #2a333d);
  border: 1px solid #55606c;
  border-radius: 10px;
  position: relative;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  /* width/height set inline by JS to card aspect */
}
.card-note {
  position: absolute; bottom: 6px; right: 10px;
  font-size: 0.7rem; color: #aeb8c2;
}
.ruler-line {
  height: 3px;
  background: var(--accent);
  position: relative;
}
.ruler-line::before, .ruler-line::after {
  content: ""; position: absolute; top: -6px; width: 2px; height: 15px; background: var(--accent);
}
.ruler-line::before { left: 0; }
.ruler-line::after { right: 0; }

.slider-row { display: flex; align-items: center; gap: 0.6rem; margin: 0.4rem 0; }
.slider-row input[type="range"] { flex: 1; }
.slider-row input[type="number"] { width: 5rem; padding: 0.3rem; background: var(--panel-2); border: 1px solid var(--line); color: var(--ink); border-radius: 6px; }

.cal-readout { font-size: 1.4rem; margin: 0.8rem 0; }
.cal-readout .muted { font-size: 0.85rem; }

.btn-row { display: flex; gap: 0.6rem; margin-top: 0.8rem; }
button.primary {
  background: var(--accent); color: #1a1a1a; border: none;
  padding: 0.55rem 1.1rem; border-radius: 9px; font-weight: 600; cursor: pointer;
}
button.ghost {
  background: transparent; color: var(--muted); border: 1px solid var(--line);
  padding: 0.55rem 1.1rem; border-radius: 9px; cursor: pointer;
}

/* ---------- play ---------- */
.wall {
  position: relative;
  height: 360px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--line);
  /* Layered granite: fine fractal-noise grain (inline SVG), broad light/dark
     mottling, then a warm base gradient. Grain is soft-light-blended so it reads
     as speckle rather than a flat overlay. */
  background-color: var(--rock);
  background-image:
    var(--grain),
    radial-gradient(120% 90% at 28% 22%, rgba(255,240,220,0.10), transparent 55%),
    radial-gradient(110% 100% at 78% 85%, rgba(0,0,0,0.38), transparent 55%),
    linear-gradient(180deg, #7c7165 0%, #574e45 60%, #443c34 100%);
  background-size: 160px 160px, cover, cover, cover;
  background-blend-mode: soft-light, normal, normal, normal;
  box-shadow: inset 0 0 70px 14px rgba(0,0,0,0.5); /* vignette for depth */
}
.crack {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 220%; /* long enough to run off both edges at any angle */
  transform-origin: center center;
  transform: translate(-50%, -50%) rotate(0deg); /* width + rotate set inline by JS */
  /* The back of the crack is heavily darkened, shading that deepens toward the
     centre (the deepest part of the gap). */
  background-color: #0d0906;
  /* Depth without blend modes: a rotated element becomes a GPU compositing
     layer, and background-blend-mode is unreliable on composited/rotated layers
     on mobile — the dropped soft-light blend exposed the opaque grain as raw
     black-and-white static at extreme angles. Horizontal gradient = deepest
     (black) down the centre; vertical gradient = subtle top-lit falloff. */
  background-image:
    linear-gradient(180deg, rgba(50,38,28,0.35) 0%, rgba(0,0,0,0.25) 100%),
    linear-gradient(90deg,
      #241b14 0%, #060403 42%, #000 50%, #060403 58%, #241b14 100%);
  background-size: 100% 100%, 100% 100%;
  box-shadow: inset 0 0 26px 6px #000, 0 0 16px 5px rgba(0,0,0,0.6);
  /* width set inline by JS from true mm × pxPerMm (perpendicular gap, angle-invariant) */
}
/* Gritty lit lips: thin warm strips at each edge, broken up by the noise alpha
   mask so the highlight reads as rough stone rather than a clean line. */
.crack::before,
.crack::after {
  content: "";
  position: absolute; top: 0; bottom: 0;
  width: 2px;
  background: rgba(255,238,214,0.6);
  -webkit-mask-image: var(--grain); mask-image: var(--grain);
  -webkit-mask-size: 22px 22px; mask-size: 22px 22px;
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
}
.crack::before { left: 0; }
.crack::after { right: 0; }

/* score / streak overlaid in the top corners of the crack window */
.hud {
  position: absolute; top: 8px; z-index: 3;
  font-size: 0.8rem; color: rgba(255,255,255,0.85);
  background: rgba(0,0,0,0.45); padding: 0.25rem 0.55rem; border-radius: 999px;
  pointer-events: none; text-shadow: 0 1px 2px #000;
}
.hud strong { color: #fff; font-size: 1rem; }
.hud-score { left: 8px; }
.hud-streak {
  right: 8px;
  transition: background 0.45s ease, box-shadow 0.45s ease, color 0.45s ease;
}
/* streak number follows the badge's (heat-dependent) text colour */
.hud-streak strong { color: inherit; }
.hud-streak.streak-max { animation: flamepulse 0.9s ease-in-out infinite alternate; }
@keyframes flamepulse {
  from { box-shadow: 0 0 14px 1px rgba(255,140,0,0.6); }
  to   { box-shadow: 0 0 26px 5px rgba(255,90,0,0.85); }
}

/* pass/fail marker centred over the crack after answering */
.verdict {
  position: absolute; inset: 0; z-index: 4;
  display: flex; align-items: center; justify-content: center;
  font-size: 8rem; line-height: 1; font-weight: 700;
  text-shadow: 0 2px 12px rgba(0,0,0,0.8);
  pointer-events: none;
}
.verdict.full { color: var(--good); }
.verdict.partial { color: var(--accent); }
.verdict.wrong { color: var(--bad); }

/* in-wall next chevron so phone users advance without scrolling */
.wall-next {
  position: absolute; top: 50%; right: 14px; transform: translateY(-50%);
  z-index: 5;
  background: none; border: none; padding: 0 0.3rem; cursor: pointer;
  color: var(--accent);
  font-size: 4rem; line-height: 1; font-weight: 700;
  text-shadow: 0 2px 8px rgba(0,0,0,0.7);
}
.wall-next:active { transform: translateY(-50%) scale(0.92); }

.prompt { text-align: center; font-size: 1.05rem; margin: 1rem 0 0.6rem; }

.gear-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
}
@media (max-width: 560px) { .gear-grid { grid-template-columns: repeat(3, 1fr); gap: 0.4rem; } }
.gear-btn {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 0.6rem 0.5rem;
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.95rem;
  transition: transform 0.05s ease, border-color 0.1s ease;
}
.gear-btn:hover:not(:disabled) { border-color: var(--accent); }
.gear-btn:active:not(:disabled) { transform: translateY(1px); }
.gear-btn:disabled { cursor: default; opacity: 0.85; }
.gear-btn .swatch { width: 18px; height: 18px; border-radius: 50%; border: 1px solid rgba(0,0,0,0.4); flex: none; }
.gear-btn .gsize { font-weight: 700; }
.gear-btn.correct { border-color: var(--good); background: #1f3524; }
.gear-btn.fits { border-color: #6ea36f; }
.gear-btn.chosen-bad { border-color: var(--bad); background: #3a1f1f; }
/* too large to display on this screen (interactive so it can explain why) */
.gear-btn.unavailable { opacity: 0.3; cursor: help; filter: grayscale(0.7); }
.gear-btn.unavailable:hover { border-color: var(--line); }   /* stay looking inert */
.gear-btn.unavailable:active { transform: none; }
.gear-note {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: var(--accent);
  background: rgba(224,169,27,0.10);
  border: 1px solid rgba(224,169,27,0.35);
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
}

/* ---------- feedback + range chart ---------- */
.feedback { margin-top: 1rem; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 1rem; }
.feedback-text { margin: 0 0 0.8rem; line-height: 1.5; }
.feedback-text .tag { font-weight: 700; }
.feedback-text .tag.full { color: var(--good); }
.feedback-text .tag.partial { color: var(--accent); }
.feedback-text .tag.wrong { color: var(--bad); }

.range-chart, .study-chart { display: flex; flex-direction: column; gap: 6px; margin: 0.6rem 0 1rem; }
.rc-row { display: grid; grid-template-columns: 3.2rem 1fr; align-items: center; gap: 0.6rem; font-size: 0.8rem; }
.rc-track { position: relative; height: 16px; background: var(--panel-2); border-radius: 4px; }
.rc-bar { position: absolute; top: 0; bottom: 0; border-radius: 4px; opacity: 0.85; }
.rc-marker { position: absolute; top: -3px; bottom: -3px; width: 2px; background: #fff; box-shadow: 0 0 4px #000; }
.rc-row.is-best .rc-track { outline: 2px solid var(--good); outline-offset: 1px; }
.rc-label { display: flex; align-items: center; gap: 0.35rem; }
.rc-label .swatch { width: 12px; height: 12px; border-radius: 50%; }

/* ---------- study ---------- */
.cam-table { width: 100%; border-collapse: collapse; margin-top: 1rem; font-size: 0.9rem; }
.cam-table th, .cam-table td { text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--line); }
.cam-table th { color: var(--muted); font-weight: 600; }
.cam-table .swatch { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 0.4rem; vertical-align: middle; }

/* study set picker + promote-to-rack */
.study-head { display: flex; gap: 0.6rem; align-items: center; margin-bottom: 0.6rem; }
.study-head #studySet { flex: 1; min-width: 0; }
/* "Make current rack" shows a confirmed state once it's the active rack */
#studyUseRack { white-space: nowrap; transition: color 0.15s ease, border-color 0.15s ease; }
#studyUseRack.is-current { color: var(--good); border-color: var(--good); opacity: 1; cursor: default; }
/* per-cam pin toggle in the table */
.pin-btn {
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--line);
  border-radius: 6px; width: 1.9rem; height: 1.7rem; cursor: pointer; line-height: 1;
  font-size: 0.9rem; padding: 0;
}
.pin-btn.active { background: var(--accent); color: #1a1a1a; border-color: var(--accent); }

/* comparison panel */
.compare { margin-top: 1.5rem; border-top: 1px solid var(--line); padding-top: 1rem; }
.compare-head { display: flex; align-items: center; justify-content: space-between; }
.compare-head h3 { margin: 0; font-size: 1rem; }
.pinned-row { display: flex; align-items: center; gap: 0.5rem; margin: 0.4rem 0; }
.pinned-row .swatch { width: 14px; height: 14px; border-radius: 50%; flex: none; }
.pinned-label {
  flex: 1; min-width: 0; padding: 0.3rem 0.5rem; background: var(--panel-2);
  border: 1px solid var(--line); color: var(--ink); border-radius: 6px; font-size: 0.85rem;
}
.pinned-src { color: var(--muted); font-size: 0.78rem; white-space: nowrap; }
.pin-remove {
  background: transparent; color: var(--muted); border: none; cursor: pointer;
  font-size: 1.1rem; line-height: 1; padding: 0 0.25rem; flex: none;
}
.pin-remove:hover { color: var(--bad); }
/* comparison chart: wider label column for custom labels */
#compareChart .rc-row { grid-template-columns: 6.5rem 1fr; }
#compareChart .rc-label { font-size: 0.72rem; line-height: 1.15; }
/* single dashed line separating the retained cams from the current set */
.rc-row.pin-sep { border-bottom: 1px dashed var(--accent); padding-bottom: 7px; margin-bottom: 3px; }

/* ---------- rack selection ---------- */
.rack-name { color: var(--muted); font-size: 0.85rem; margin: 0.8rem 0 0; text-align: center; }
.rack-name strong { color: var(--ink); }
.rack-change { color: var(--accent); margin-left: 0.5rem; font-size: 0.8rem; }
.rack-list { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 1rem; }
.rack-item {
  display: flex; flex-direction: column; gap: 0.15rem; text-align: left;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--ink); border-radius: 10px; padding: 0.7rem 0.9rem; cursor: pointer;
}
.rack-item:hover { border-color: var(--accent); }
.rack-item.active { border-color: var(--accent); background: #2c2a1c; }
.rack-item-name { font-weight: 700; }
.rack-item-meta { color: var(--muted); font-size: 0.8rem; }

.view { animation: fade 0.15s ease; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------- adventure mode ---------- */
#view-adventure { position: relative; }
.adv-top { display: flex; gap: 0.6rem; align-items: stretch; }
.adv-top .wall { flex: 1; }
/* wall turns danger-red at the edges when a fall would be scary */
.wall.scared { box-shadow: inset 0 0 70px 18px rgba(204,51,51,0.55); }
.hud-stance { right: 8px; background: rgba(0,0,0,0.55); }
/* "Too big" / "Too small" shown over the crack on a misfit placement */
.adv-fit-msg {
  position: absolute; inset: 0; z-index: 7;
  display: flex; align-items: center; justify-content: center;
  font-size: 2.4rem; font-weight: 800; color: var(--bad);
  text-shadow: 0 2px 12px rgba(0,0,0,0.9);
  pointer-events: none;
}
/* result of an attempt (FLASH / Nice Send / falls) shown over the crack window */
.adv-result-msg {
  position: absolute; inset: 0; z-index: 8;
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-size: 2.2rem; font-weight: 800; padding: 0 0.5rem; line-height: 1.1;
  text-shadow: 0 2px 14px rgba(0,0,0,0.95);
  pointer-events: none;
}
.adv-result-msg.send { color: var(--good); }
.adv-result-msg.send-flash { color: var(--accent); }
.adv-result-msg.fall { color: var(--bad); }

/* vertical route gauge: 0ft at bottom → 100ft at top */
.route-gauge {
  position: relative; width: 56px; flex: none;
  border-radius: 10px; border: 1px solid var(--line);
  background: linear-gradient(180deg, #2a333d, #1b2129);
  overflow: hidden;
}
/* crack-width profile + stance bands (stretched to fill the gauge) */
.gauge-svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* ground line at the very bottom */
.route-gauge::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: #6b6157;
}
.gauge-fall {
  position: absolute; left: 6px; right: 6px;
  background: rgba(224,169,27,0.28); border-radius: 3px;
}
.gauge-fall.danger { background: rgba(204,51,51,0.4); }
/* fuzzy extension = rope-stretch uncertainty, fading out toward the deepest reach */
.gauge-fall-fuzz {
  position: absolute; left: 6px; right: 6px;
  background: linear-gradient(180deg, rgba(224,169,27,0.26), rgba(224,169,27,0));
}
.gauge-fall-fuzz.danger { background: linear-gradient(180deg, rgba(204,51,51,0.38), rgba(204,51,51,0)); }
.gauge-gear {
  position: absolute; left: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px;
  border-radius: 50%; border: 1px solid rgba(0,0,0,0.5); z-index: 2;
}
.gauge-climber {
  position: absolute; left: 50%; width: 16px; height: 16px; margin: -8px 0 0 -8px;
  border-radius: 50%; background: #fff; border: 2px solid var(--accent);
  box-shadow: 0 0 8px rgba(0,0,0,0.6); z-index: 3;
}

.adv-stamina { display: flex; align-items: center; gap: 0.6rem; margin: 0.7rem 0 0.4rem; }
.adv-stamina-label { font-size: 0.8rem; color: var(--muted); white-space: nowrap; }
.adv-stamina .rc-track { flex: 1; height: 18px; }
.adv-stamina .rc-bar { top: 0; bottom: 0; left: 0; border-radius: 4px; transition: width 0.12s linear; }
.adv-fear .adv-stamina-label { color: var(--muted); }
.adv-fear.fear-high .rc-track { animation: flamepulse 0.9s ease-in-out infinite alternate; }

.adv-readouts { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.7rem; }
.adv-chip {
  display: inline-flex; align-items: baseline; gap: 0.3rem;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
  padding: 0.2rem 0.6rem; font-size: 0.85rem;
}
.adv-chip .k { color: var(--muted); font-size: 0.75rem; }
.adv-chip .v { font-weight: 700; }
.adv-chip.scared { color: var(--bad); border-color: var(--bad); font-weight: 700;
  animation: flamepulse 0.9s ease-in-out infinite alternate; }

.adv-controls { margin-top: 0.8rem; text-align: center; }
.adv-controls .primary { font-size: 1.05rem; padding: 0.7rem 1.6rem; }

.adv-outcome { margin-top: 0.9rem; text-align: center; }
.adv-outcome-msg { font-size: 1.5rem; font-weight: 700; margin: 0 0 0.7rem; }
.adv-outcome-msg.send { color: var(--good); }
.adv-outcome-msg.send-flash { color: var(--accent); }
.adv-outcome-msg.fall { color: var(--bad); }
.adv-outcome .btn-row { justify-content: center; }

/* cam-placement animation: a colored cam, sized to the crack, rises in with lobes
   retracted, then the lobes spring to an intermediate spread and the cam stays put. */
.cam-anim {
  position: absolute; left: 50%; top: 50%; z-index: 6;
  transform: translate(-50%, -50%);   /* width/height set inline by JS to match the crack */
  pointer-events: none;
}
.cam-anim-move { width: 100%; height: 100%; }
.cam-anim svg {
  width: 100%; height: 100%; display: block;
  stroke: rgba(255,255,255,0.35); stroke-width: 7px; /* keeps dark cams visible */
  filter: drop-shadow(0 2px 5px rgba(0,0,0,0.7));
}
/* lobes rest at the intermediate spread, so the placed cam holds this look */
.cam-anim .cam-lobes { transform-box: fill-box; transform-origin: center; transform: scaleX(0.7); }
.cam-anim.play .cam-anim-move { animation: cam-place 1.15s cubic-bezier(.2,.7,.3,1) forwards; }
@keyframes cam-place {
  0%   { transform: translateY(180px) scale(0.9); opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
.cam-anim.play .cam-lobes { animation: cam-lobes 1.15s cubic-bezier(.2,.7,.3,1) forwards; }
@keyframes cam-lobes {
  0%, 45% { transform: scaleX(0.2); }   /* pulled in tight while entering */
  80%     { transform: scaleX(0.8); }   /* small overshoot */
  100%    { transform: scaleX(0.7); }   /* settle at intermediate spread */
}

/* spent cams in the inventory */
.gear-btn.used { opacity: 0.3; filter: grayscale(0.8); cursor: default; }

/* confetti burst on a flash send */
.confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 20; }
.confetti-bit {
  position: absolute; top: -12px; width: 8px; height: 12px; border-radius: 1px;
  animation: confetti-fall 2.4s linear forwards;
}
@keyframes confetti-fall {
  from { transform: translateY(0) translateX(0) rotate(var(--rot)); opacity: 1; }
  to   { transform: translateY(115vh) translateX(var(--drift)) rotate(calc(var(--rot) + 540deg)); opacity: 0.9; }
}

/* keep the (now busier) menu bar from overflowing on small screens */
@media (max-width: 560px) {
  .topbar { flex-wrap: wrap; row-gap: 0.4rem; column-gap: 0.5rem; }
  .tab { padding: 0.35rem 0.55rem; font-size: 0.9rem; }
}
