/* premium.css */
/* ===========================================================================
   WarriorIQ premium surface layer.

   Loaded last, additive only: it introduces no new markup requirements and
   overrides nothing structural, so a failure here degrades to the existing
   design rather than breaking a page.

   The flat single-tone canvas is what made the product read as cheap. Depth
   here comes from three things real high-end interfaces use and this build had
   none of: a coloured atmosphere behind the content, a grain layer that stops
   large dark gradients banding on cheap panels, and light-catching edges on the
   surfaces that matter. All of it is drawn from the existing token palette.
   =========================================================================== */

:root {
  --wiq-aurora-a: 92 130 239;   /* --wiq-blue  */
  --wiq-aurora-b: 85 198 223;   /* --wiq-cyan  */
  --wiq-aurora-c: 160 138 232;  /* --wiq-b     */
  --wiq-edge: rgba(255, 255, 255, .07);
  --wiq-edge-strong: rgba(255, 255, 255, .14);
  --wiq-lift: 0 1px 0 rgba(255,255,255,.05) inset, 0 24px 60px -28px rgba(0,0,0,.85);
}

/* The canvas gradient moves to <html> and body goes transparent. body paints
   an opaque background over its own root, which would bury the atmosphere
   layers below; hoisting it one level up lets them sit between the canvas and
   the content instead of behind everything. */
html {
  background: var(--wiq-canvas);
  min-height: 100%;
}
body { background: transparent; }

/* Content sits above the decoration without either needing a negative index,
   which is what put these layers behind the canvas in the first place. Only the
   shell needs a position; the overlays are already fixed and must keep that, so
   they are raised by z-index alone. */
.shell { position: relative; z-index: 1; }
.cookie-notice, .app-toast, .page-scroll-progress { z-index: 40; }

/* --- Atmosphere -----------------------------------------------------------
   Three oversized, heavily feathered colour fields behind everything. Fixed so
   they behave like a lit room rather than a background image that scrolls, and
   pointer-events:none so they can never intercept a click. Drawn on <html>
   because body::before already carries the existing grid overlay, which this
   layer sits behind rather than replaces. */

@keyframes wiq-aurora {
  0%   { transform: translate3d(0,0,0) scale(1); }
  50%  { transform: translate3d(-2.5%, 1.5%, 0) scale(1.06); }
  100% { transform: translate3d(2%, -2%, 0) scale(1.02); }
}

/* --- Grain ----------------------------------------------------------------
   Large dark gradients band badly on 6-bit and mid-range phone panels, which is
   most of the audience. A faint noise field breaks the ramp and is the single
   cheapest thing that makes a dark interface look finished. */

/* --- Surfaces -------------------------------------------------------------
   A hairline of light along the top edge reads as a physical bevel and is what
   separates a "card" from a rectangle with a border. */
.card,
.hero-card,
.pricing-card,
.analysis-process-card,
.trust-panel {
  position: relative;
  border-color: var(--wiq-edge);
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 24px 60px -28px rgba(0,0,0,.85);
  background-image: linear-gradient(180deg, rgba(255,255,255,.028), transparent 42%);
}

.card::before,
.hero-card::before,
.pricing-card::before {
  content: "";
  position: absolute;
  inset-inline: 12%;
  top: -1px;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--wiq-edge-strong), transparent);
}

.card:hover,
.pricing-card:hover {
  border-color: rgb(var(--wiq-aurora-a) / .38);
}

/* The featured plan earns a lit edge rather than only a louder colour. */
.pricing-card.featured,
.pricing-card.gym-featured {
  background-image:
    linear-gradient(180deg, rgb(var(--wiq-aurora-a) / .10), transparent 46%),
    linear-gradient(180deg, rgba(255,255,255,.03), transparent 40%);
  box-shadow: 0 1px 0 rgba(255,255,255,.07) inset, 0 30px 70px -30px rgba(24,48,120,.75);
}

/* --- Type -----------------------------------------------------------------
   Display type at this size needs negative tracking and a tighter leading; the
   default spacing is what makes a headline look like body copy scaled up. */
.hero h1,
.pricing-hero h1,
.workflow-heading h1 {
  letter-spacing: -.028em;
  line-height: .96;
  text-wrap: balance;
}

.hero-copy p,
.pricing-hero p {
  text-wrap: pretty;
}

/* --- Primary action -------------------------------------------------------
   A flat fill reads as a default button. A vertical gradient plus a lit top
   edge is what separates a product's primary action from a form control. */
.btn:not(.secondary) {
  background-image: linear-gradient(180deg, rgba(255,255,255,.16), transparent 58%);
  box-shadow: 0 1px 0 rgba(255,255,255,.22) inset, 0 12px 26px -12px rgba(41,75,158,.9);
}

.btn:not(.secondary):hover {
  box-shadow: 0 1px 0 rgba(255,255,255,.28) inset, 0 16px 32px -12px rgba(41,75,158,1);
}

/* Respect the system preference: the atmosphere stays, the drift stops. */
@media (prefers-reduced-motion: reduce) {
  html::before { animation: none; }
}

/* Keep the effect affordable on small screens, where the blur is the most
   expensive part of the frame and the least visible. */
@media (max-width: 720px) {
  html::before { filter: blur(18px) saturate(110%); animation: none; }
  html::after { opacity: .026; }
}

/* A forced-colours user has asked the OS to drop decoration entirely. */
@media (forced-colors: active) {
  html::before, html::after { display: none; }
}

/* ===========================================================================
   Redesign layer.
   =========================================================================== */

/* --- The typeface ---------------------------------------------------------
   The stylesheets asked for Inter and no webfont was ever served, so the whole
   product fell back to Segoe UI or Arial. The design was drawn for a typeface
   it never received, which is most of why it read as generic. Self-hosted
   rather than loaded from Google Fonts: this is an EU product with a strict
   privacy posture, and a third-party font request leaks every visitor's IP to
   a US ad company before they have consented to anything. */
@font-face {
  font-family: "InterVar";
  src: url("/static/fonts/inter-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --font-display: "InterVar", Inter, "Segoe UI", system-ui, sans-serif;
  --font-body: "InterVar", Inter, "Segoe UI", system-ui, sans-serif;
  /* Optical sizing and a slightly tighter tracking are what make Inter look
     drawn rather than defaulted. */
  --wiq-radius-lg: 22px;
  --wiq-radius-md: 15px;
}

body {
  font-family: var(--font-body);
  font-feature-settings: "cv05" 1, "ss03" 1, "tnum" 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* --- Rhythm ---------------------------------------------------------------
   Expensive layouts are mostly space. The grid was tight enough that every
   section fought its neighbour for attention; letting each one breathe is the
   single largest change here and needs no markup edits. */
.hero { padding-block: clamp(28px, 6vw, 76px); }
.card, .hero-card { padding: clamp(22px, 2.6vw, 34px); }
section + section, .pricing-grid, .grid3 { margin-top: clamp(28px, 5vw, 72px); }
.pricing-grid, .grid3 { gap: clamp(14px, 1.6vw, 22px); }

/* Grid children are not page sections. The rule above is page-level rhythm,
   but cards are <section> too, so inside a grid it lands on every card except
   the first and drops the row out of alignment: on /pricing that is a 72px
   step between card 1 and the two beside it, and on /compare it is why the
   second "Fight analysis" card hangs below the first. Each grid already
   declares a gap, which owns the spacing between its children at every
   breakpoint including the stacked one, so there is nothing to put back. */
.pricing-grid > section + section,
.compare-grid > section + section,
.grid3 > section + section { margin-top: 0; }

/* The sibling margin was also the only thing separating these cards once they
   stack, so removing it alone would leave them 14px apart on a phone. Put the
   space back as row-gap: it applies between rows and never between columns,
   which is the whole reason the margin misaligned the row. */
@media (max-width: 950px) {
  .pricing-grid, .compare-grid, .grid3 { row-gap: clamp(24px, 6vw, 34px); }
}

/* --- Hierarchy ------------------------------------------------------------
   The eyebrow, heading and body were all competing at similar weight. Pulling
   the eyebrow back to a quiet label and letting the heading carry the page is
   what separates an editorial layout from a dense one. */
.eyebrow {
  font-size: 11px;
  letter-spacing: .16em;
  font-weight: 650;
  color: var(--wiq-text-tertiary);
}

h2 { letter-spacing: -.032em; text-wrap: balance; }
h3 { letter-spacing: -.018em; }

.muted, .small { color: var(--wiq-text-secondary); }
p { max-width: 68ch; }

/* Numerals in measurements should line up in a column, not wobble. */
.plan-price, .allowance-strip strong, .console-allowance, [class*="metric"] {
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}

/* --- Controls -------------------------------------------------------------
   Larger targets and a softer radius. The 8px radius on 44px controls read as
   utilitarian; matching the curve to the control height is what makes a form
   feel considered. */
.btn {
  border-radius: 11px;
  padding-inline: 20px;
  letter-spacing: .004em;
}

.field input, .field select, .field textarea {
  border-radius: 11px;
  min-height: 46px;
}

.field label, .field > span:first-child {
  letter-spacing: .1em;
  font-size: var(--wiq-text-micro);
}

/* --- Restraint ------------------------------------------------------------
   Accent colour was doing too many jobs at once. Reserving full-strength blue
   for the primary action, and letting secondary surfaces sit quieter, is what
   makes the one thing you want clicked actually stand out. */
.btn.secondary {
  background: rgba(255,255,255,.035);
  border-color: var(--wiq-edge-strong);
  box-shadow: none;
}
.btn.secondary:hover {
  background: rgba(255,255,255,.06);
  border-color: rgb(var(--wiq-aurora-a) / .34);
}

.pill, .check, .trust-checks span {
  border-radius: 999px;
  border-color: var(--wiq-edge);
  background: rgba(255,255,255,.026);
}

/* --- Navigation -----------------------------------------------------------
   A quiet bar that separates by tone rather than a hard rule. */
.nav {
  border-bottom: 1px solid var(--wiq-edge);
  backdrop-filter: saturate(140%) blur(10px);
}
.navlinks a { letter-spacing: .002em; }
.navlinks a[aria-current="page"] { color: var(--wiq-text); }

/* --- Upload feedback ------------------------------------------------------
   The size line changes tone with the file, because a 700 MB phone video and a
   40 MB clip are not the same decision and the old interface said the same
   thing for both. */
.file-status[data-tone="warn"] { color: var(--wiq-warning); }
.file-status[data-tone="note"] { color: var(--wiq-text-secondary); }
.file-status[data-tone="ok"]   { color: var(--wiq-success); }
.upload-progress b { font-variant-numeric: tabular-nums; }

/* --- Sport picker ---------------------------------------------------------
   Five sports across ten disciplines. A flat select buries the one a visitor
   came for, so the sport is chosen first as a visible set of choices and the
   ruleset list narrows to it. Built from radio inputs so it is keyboard and
   screen-reader native, and works with JavaScript off.
   --------------------------------------------------------------------------- */
/* A grid rather than a wrapping flex row. Five chips never fit on one line in
   the upload column, and free wrapping leaves a single orphan on the second
   row that reads as a mistake; auto-fit spreads them evenly instead (3 + 2 in
   the card, one line where there is room for it). */
.sport-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}

.sport-option { position: relative; cursor: pointer; }

/* The input stays focusable and reachable; only its default box is hidden. */
.sport-option input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.sport-option span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--wiq-edge);
  border-radius: 999px;
  background: rgba(255, 255, 255, .026);
  color: var(--wiq-text-secondary);
  font-size: 13px;
  font-weight: 620;
  /* .field label uppercases its contents, which is right for the field's own
     caption and wrong for these: the sport names are choices, not labels, and
     tracked-out capitals widen the row enough to push MMA onto a second line. */
  text-transform: none;
  letter-spacing: .004em;
  transition: border-color var(--wiq-fast) var(--wiq-ease),
              background-color var(--wiq-fast) var(--wiq-ease),
              color var(--wiq-fast) var(--wiq-ease);
}

.sport-option:hover span { border-color: var(--wiq-edge-strong); color: var(--wiq-text); }

.sport-option input:checked + span {
  border-color: rgb(var(--wiq-aurora-a) / .55);
  background: rgb(var(--wiq-aurora-a) / .16);
  color: var(--wiq-text);
}

/* The focus ring has to follow the visible chip, not the hidden input. */
.sport-option input:focus-visible + span {
  outline: 2px solid #82a5ff;
  outline-offset: 3px;
}

.sport-field { margin-bottom: 4px; }

/* --- Coverage disclosure --------------------------------------------------
   The picker offers five sports; the detector reads punches, kicks and knees.
   For boxing and kickboxing those are the same set, for MMA they are nowhere
   near it. This note is the honest half of the choice, so it is styled to be
   read rather than skimmed past: it sits inside the field, tied to the sport
   above it, and changes tone when coverage is partial.
   --------------------------------------------------------------------------- */
.sport-coverage {
  margin: 10px 0 0;
  padding: 11px 13px;
  border: 1px solid var(--wiq-edge);
  border-left: 2px solid var(--wiq-success);
  border-radius: 0 10px 10px 0;
  background: rgba(255, 255, 255, .022);
  color: var(--wiq-text-secondary);
  font-size: 12px;
  line-height: 1.6;
  /* The picker sets a max-width for prose elsewhere; this must fill its field. */
  max-width: none;
}

.sport-coverage b { color: var(--wiq-text); font-weight: 700; }

/* Partial coverage is not an error, so it is amber rather than red: the
   analysis is still correct about what it saw. */
.sport-coverage[data-covered="no"] {
  border-left-color: var(--wiq-warning);
}

.sport-coverage[hidden] { display: none; }

/* --- Hero sport rail ------------------------------------------------------
   A pill reading "5 sports" asks the visitor to take the claim on trust and
   tells a boxer nothing. Naming them is the whole message of this release, so
   the hero states them outright.
   --------------------------------------------------------------------------- */
.sport-rail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px 10px;
  margin-top: 16px;
  color: var(--wiq-text-tertiary);
  font-size: 12px;
}

.sport-rail b {
  color: var(--wiq-text-secondary);
  font-weight: 620;
  letter-spacing: .003em;
  white-space: nowrap;
}

/* Hairline separators drawn between names only, so the list reads as one line
   of type rather than a row of buttons competing with the hero call to action. */
.sport-rail b + b::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 10px;
  margin-right: 10px;
  vertical-align: -1px;
  background: var(--wiq-edge-strong);
}

@media (max-width: 620px) {
  .sport-rail { font-size: 11px; gap: 6px 8px; }
  .sport-rail b + b::before { margin-right: 8px; }
}

/* --- Coverage limit on the report ----------------------------------------
   The same disclosure the picker makes, repeated where the number actually
   appears. Amber rather than red: nothing here is wrong, the analysis is
   simply answering a narrower question than the sport asks.
   --------------------------------------------------------------------------- */
.coverage-notice {
  border-left-color: var(--wiq-warning);
}

.coverage-line {
  margin-top: 8px;
  padding-left: 11px;
  border-left: 2px solid var(--wiq-warning);
  color: var(--wiq-text-secondary);
}

/* ===========================================================================
   Sport-first flow: home → choose a sport → set that sport up.

   The old home page asked for a video, a sport, a ruleset, a format and two
   consents in one column beside the headline. Everything now follows from the
   sport, so the sport is asked first, on its own, and the hero goes back to
   doing one job: saying what this is and offering a single way in.
   =========================================================================== */

/* --- Centered hero -------------------------------------------------------- */
.hero-centered {
  display: block;
  min-height: 0;
  padding: clamp(56px, 11vh, 116px) 0 clamp(44px, 8vh, 84px);
  text-align: center;
}

.hero-centered .hero-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Measure, not the full 1280px shell: a centered line longer than this stops
     being readable as a paragraph and starts being a banner. */
  max-width: 860px;
  margin: 0 auto;
}

.hero-centered .hero-copy > p {
  max-width: 62ch;
  margin-inline: auto;
  text-wrap: pretty;
}

.hero-centered .hero-actions,
.hero-centered .fight-path,
.hero-centered .trust-row,
.hero-centered .sport-rail { justify-content: center; }

.hero-centered .eyebrow::before { display: none; }

/* The single way in earns more weight than a row of equal buttons. */
.btn-lead {
  min-height: 54px;
  padding-inline: 30px;
  font-size: 15px;
}

/* --- The five sports ------------------------------------------------------ */
.chooser { padding: clamp(40px, 8vh, 88px) 0 clamp(48px, 9vh, 96px); }

.chooser-head { max-width: 720px; margin-bottom: clamp(28px, 5vh, 52px); }
.chooser-head h1 { margin: 10px 0 14px; font-size: clamp(38px, 5.4vw, 66px); line-height: .98; }
.chooser-head p { color: var(--wiq-text-secondary); line-height: 1.65; }

.sport-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

@media (min-width: 760px)  { .sport-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1180px) { .sport-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.sport-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-height: 186px;
  padding: 24px 24px 22px;
  border: 1px solid var(--wiq-edge);
  border-radius: 16px;
  background: linear-gradient(160deg, rgba(255,255,255,.045), rgba(255,255,255,.014));
  box-shadow: var(--wiq-lift);
  overflow: hidden;
  transition: border-color var(--wiq-fast) var(--wiq-ease),
              transform var(--wiq-fast) var(--wiq-ease);
}

/* A wash that only resolves on the hovered card, so the grid reads as one
   surface at rest instead of five competing panels. */
.sport-card-mark {
  position: absolute;
  inset: -40% -30% auto auto;
  width: 260px;
  height: 260px;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(var(--wiq-aurora-a) / .30), transparent 66%);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--wiq-slow, 280ms) var(--wiq-ease);
}

.sport-card:hover { border-color: var(--wiq-edge-strong); transform: translateY(-3px); }
.sport-card:hover .sport-card-mark { opacity: 1; }
.sport-card:focus-visible { outline: 2px solid #82a5ff; outline-offset: 3px; }

.sport-card h2 { margin: 0; font-size: 25px; letter-spacing: -.02em; }

.sport-card-rules {
  margin: 0;
  color: var(--wiq-text-tertiary);
  font-size: 11.5px;
  line-height: 1.5;
}

.sport-card-coverage {
  margin-top: auto;
  padding-top: 14px;
  color: var(--wiq-success);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .01em;
}

.sport-card-coverage[data-covered="no"] { color: var(--wiq-warning); }

.sport-card-go {
  position: absolute;
  right: 22px;
  bottom: 20px;
  color: var(--wiq-text-tertiary);
  font-size: 17px;
  transition: transform var(--wiq-fast) var(--wiq-ease), color var(--wiq-fast) var(--wiq-ease);
}

.sport-card:hover .sport-card-go { transform: translateX(4px); color: var(--wiq-text); }

.chooser-note { max-width: 68ch; margin-top: 26px; }

/* --- One sport's setup ---------------------------------------------------- */
.setup {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(28px, 5vw, 64px);
  align-items: start;
  padding: clamp(34px, 6vh, 70px) 0 clamp(48px, 8vh, 92px);
}

.setup-head { position: sticky; top: 104px; }
.setup-head .quiet-back { display: inline-block; margin-bottom: 16px; }
.setup-head h1 { margin: 10px 0 18px; font-size: clamp(32px, 3.9vw, 50px); line-height: 1; }

.setup-coverage {
  margin: 0;
  padding: 13px 15px;
  border: 1px solid var(--wiq-edge);
  border-left: 2px solid var(--wiq-success);
  border-radius: 0 11px 11px 0;
  background: rgba(255, 255, 255, .022);
  color: var(--wiq-text-secondary);
  font-size: 12.5px;
  line-height: 1.62;
}

.setup-coverage[data-covered="no"] { border-left-color: var(--wiq-warning); }
.setup-coverage b { color: var(--wiq-text); }

.setup-card {
  padding: clamp(22px, 3vw, 30px);
  border: 1px solid var(--wiq-edge);
  border-radius: 18px;
  background: linear-gradient(160deg, rgba(255,255,255,.05), rgba(255,255,255,.015));
  box-shadow: var(--wiq-lift);
}

@media (max-width: 980px) {
  .setup { grid-template-columns: 1fr; }
  .setup-head { position: static; }
}

@media (max-width: 620px) {
  .sport-grid { grid-template-columns: 1fr; gap: 11px; }
  .sport-card { min-height: 0; padding: 19px; }
  .sport-card h2 { font-size: 21px; }
  .btn-lead { width: 100%; }
}

.chooser-limit {
  margin: 18px 0 0;
  padding: 12px 15px;
  border: 1px solid var(--wiq-edge);
  border-left: 2px solid var(--wiq-warning);
  border-radius: 0 11px 11px 0;
  background: rgba(255, 255, 255, .022);
  color: var(--wiq-text-secondary);
  font-size: 12.5px;
}
.chooser-limit b { color: var(--wiq-text); }

/* ===========================================================================
   Sport identity.

   Five sports that share a chassis but must not feel interchangeable. Each
   carries an accent and a two-letter crest, set as custom properties on the
   element by the server from core/sport_profiles.py — so the palette has one
   source and cannot drift from the coaching built on the same data.

   Everything below falls back to the house blue, so a page that does not know
   its sport is styled, not broken.
   =========================================================================== */
:root { --sport-accent: var(--wiq-aurora-a); --sport-accent-soft: 150 178 255; }

/* --- Crest ---------------------------------------------------------------- */
.sport-crest {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border: 1px solid rgb(var(--sport-accent) / .42);
  border-radius: 13px;
  background: linear-gradient(150deg, rgb(var(--sport-accent) / .24), rgb(var(--sport-accent) / .07));
  color: rgb(var(--sport-accent-soft));
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .06em;
  /* Optical centring: the tracking above pushes the pair right by half a step. */
  text-indent: .06em;
}

/* --- Chooser cards, in their own colour ----------------------------------- */
.sport-card-mark {
  background: radial-gradient(circle, rgb(var(--sport-accent) / .34), transparent 66%);
}

.sport-card { gap: 9px; }
.sport-card .sport-crest { width: 38px; height: 38px; border-radius: 11px; font-size: 12px; }
.sport-card:hover { border-color: rgb(var(--sport-accent) / .5); }
.sport-card:hover h2 { color: rgb(var(--sport-accent-soft)); }
.sport-card h2 { transition: color var(--wiq-fast) var(--wiq-ease); }

.sport-card-decided {
  margin: 0;
  color: var(--wiq-text-secondary);
  font-size: 12.5px;
  line-height: 1.55;
}

.sport-card-rules {
  margin: 0;
  padding-top: 2px;
  color: var(--wiq-text-tertiary);
  font-size: 11px;
  letter-spacing: .012em;
}

.sport-card-go { color: rgb(var(--sport-accent-soft)); opacity: .55; }
.sport-card:hover .sport-card-go { opacity: 1; }

/* --- Setup page ----------------------------------------------------------- */
.setup-title { display: flex; align-items: center; gap: 14px; }
.setup-title h1 { margin: 0; }
.setup-head .eyebrow { color: rgb(var(--sport-accent-soft)); }
.setup-head .eyebrow::before { background: rgb(var(--sport-accent)); }

.setup-decided {
  margin: 14px 0 18px;
  max-width: 46ch;
  color: var(--wiq-text-secondary);
  font-size: 14px;
  line-height: 1.6;
}

.setup-card { border-top: 2px solid rgb(var(--sport-accent) / .5); }

/* --- The sport panel on a report ------------------------------------------ */
.sport-panel { border-top: 2px solid rgb(var(--sport-accent) / .5); }
.sport-panel-head { display: flex; align-items: flex-start; gap: 15px; }
.sport-panel-head h2 { margin: 6px 0 0; }
.sport-panel-head .eyebrow { color: rgb(var(--sport-accent-soft)); }

.sport-panel-frame {
  margin: 8px 0 0;
  max-width: 62ch;
  color: var(--wiq-text-secondary);
  font-size: 13px;
  line-height: 1.6;
}

/* Two bars per family: what the ruleset pays for, and what was thrown. Reading
   them as a pair is the point, so they share a track and sit flush. */
.weapon-mix { margin: 26px 0 4px; }

.weapon-mix-caption {
  margin: 0 0 18px;
  max-width: 64ch;
  color: var(--wiq-text-tertiary);
  font-size: 11.5px;
  line-height: 1.6;
}

.weapon-row {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
  padding: 14px 0;
  border-top: 1px solid var(--wiq-line-soft);
}

.weapon-row > b {
  color: var(--wiq-text);
  font-size: 13px;
  font-weight: 650;
}

.weapon-bars { display: grid; gap: 7px; min-width: 0; }

/* Series name, track, value. Fixed columns, so a label never has to dodge its
   own fill and the two rows stay comparable at every width. */
.weapon-bar {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr) 42px;
  gap: 12px;
  align-items: center;
}

.weapon-bar small {
  color: var(--wiq-text-tertiary);
  font-size: var(--wiq-text-micro);
  letter-spacing: .01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.weapon-bar i {
  display: block;
  height: 12px;
  width: 100%;
  border-radius: 4px;
  background: rgba(255, 255, 255, .05);
  /* The fill is drawn with a gradient stop rather than a nested element, so the
     track keeps its full width and the rows stay aligned. */
  background-image: linear-gradient(90deg,
    rgb(var(--sport-accent) / .34) 0 var(--w, 0%),
    transparent var(--w, 0%) 100%);
  background-repeat: no-repeat;
}

.weapon-bar.thrown i {
  background-image: linear-gradient(90deg,
    rgb(var(--sport-accent)) 0 var(--w, 0%),
    transparent var(--w, 0%) 100%);
}

.weapon-bar > b {
  color: var(--wiq-text);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.weapon-bar.reward > b { color: var(--wiq-text-secondary); font-weight: 600; }

.sport-observations { margin: 24px 0 0; padding: 0; list-style: none; }

.sport-observations li {
  display: grid;
  gap: 4px;
  padding: 15px 0 15px 15px;
  border-top: 1px solid var(--wiq-line-soft);
  border-left: 2px solid var(--wiq-success);
}

.sport-observations li[data-tone="improvement"] { border-left-color: var(--wiq-warning); }
.sport-observations strong { font-size: 13.5px; }
.sport-observations span { color: var(--wiq-text-secondary); font-size: 12.5px; line-height: 1.6; }

.sport-panel-limit {
  margin: 22px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--wiq-line-soft);
  color: var(--wiq-text-tertiary);
  font-size: 11.5px;
  line-height: 1.6;
}
.sport-panel-limit b { color: var(--wiq-text-secondary); }

@media (max-width: 620px) {
  .setup-title { gap: 11px; }
  .sport-crest { width: 36px; height: 36px; border-radius: 10px; font-size: 11px; }
  .weapon-row { grid-template-columns: minmax(0, 1fr); gap: 9px; }
  .weapon-row > b { font-size: 12.5px; }
  .weapon-bar {
    grid-template-columns: minmax(0, 1fr) 46px;
    grid-template-areas: "label value" "track track";
    gap: 4px 10px;
  }
  .weapon-bar small { grid-area: label; }
  .weapon-bar i { grid-area: track; }
  .weapon-bar > b { grid-area: value; }
}

/* --- Interaction floor ----------------------------------------------------
   From the UI/UX audit: every control a finger has to hit needs 44x44px, and
   nothing interactive should be reachable only by hover. These are the few
   places in the new flow that were under the line.
   --------------------------------------------------------------------------- */
.sport-option span { min-height: 44px; }
.sport-option, .sport-card, .file-button { cursor: pointer; }

/* The crest is decorative; the whole card is the target, so the card carries
   the focus ring rather than anything inside it. */
.sport-card:focus-visible { outline-offset: 4px; }

/* Motion stays inside the 200-300ms band the style guidance calls for, and
   stops entirely when the reader has asked for that. */
@media (prefers-reduced-motion: reduce) {
  .sport-card, .sport-card-mark, .sport-card-go, .sport-option span { transition: none; }
  .sport-card:hover { transform: none; }
}

/* motion.css */
:root{
  --wiq-motion-fast:140ms;
  --wiq-motion-base:260ms;
  --wiq-motion-slow:420ms;
  --wiq-ease-out:cubic-bezier(.2,.82,.2,1);
  --wiq-ease-impact:cubic-bezier(.18,.89,.32,1.22);
}

html{scrollbar-width:thin;scrollbar-color:#5369c7 #090f1e}
html::-webkit-scrollbar{width:10px;height:10px}
html::-webkit-scrollbar-track{background:#090f1e}
html::-webkit-scrollbar-thumb{border:2px solid #090f1e;border-radius:10px;background:#5369c7}
html::-webkit-scrollbar-thumb:hover{background:#7084df}

.page-scroll-progress{position:fixed;z-index:500;inset:0 0 auto;height:2px;pointer-events:none;background:transparent}
.page-scroll-progress i{display:block;width:100%;height:100%;background:linear-gradient(90deg,#4fd7ff,#7984ff);transform:scaleX(0);transform-origin:left;will-change:transform}

body.motion-enabled .shell{animation:wiq-page-enter var(--wiq-motion-slow) var(--wiq-ease-out) both}
body.motion-enabled .wiq-reveal{opacity:0;transform:translateY(18px);transition:opacity var(--wiq-motion-slow) var(--wiq-ease-out),transform var(--wiq-motion-slow) var(--wiq-ease-out);transition-delay:calc(var(--wiq-reveal-order,0)*55ms)}
body.motion-enabled .wiq-reveal.is-visible{opacity:1;transform:none}

.nav{transition:border-color var(--wiq-motion-base) ease,background-color var(--wiq-motion-base) ease,box-shadow var(--wiq-motion-base) ease}
.brand-logo{transition:transform var(--wiq-motion-base) var(--wiq-ease-impact)}
.brand:hover .brand-logo{transform:rotate(-4deg) scale(1.06)}
.navlinks>a,.nav-more>summary{transition:color var(--wiq-motion-fast) ease,background-color var(--wiq-motion-fast) ease,transform var(--wiq-motion-fast) var(--wiq-ease-out)}
.navlinks>a:active,.nav-more>summary:active{transform:translateY(1px)}
.mobile-menu:not([hidden]){transform-origin:top;animation:wiq-menu-in var(--wiq-motion-base) var(--wiq-ease-out) both}
.mobile-menu-button span{transform-origin:center;transition:transform var(--wiq-motion-base) var(--wiq-ease-out),opacity var(--wiq-motion-fast) ease}
.mobile-menu-button[aria-expanded=true] span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.mobile-menu-button[aria-expanded=true] span:nth-child(2){opacity:0}
.mobile-menu-button[aria-expanded=true] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

.btn,.file-button,.target-options label,.report-path a,.timeline button{transition:transform var(--wiq-motion-fast) var(--wiq-ease-out),border-color var(--wiq-motion-base) ease,background-color var(--wiq-motion-base) ease,box-shadow var(--wiq-motion-base) ease,filter var(--wiq-motion-base) ease}
.btn:active:not(:disabled),.file-button:active,.target-options label:active,.report-path a:active,.timeline button:active{transform:translateY(1px) scale(.985)}
.wiq-primary-motion{--wiq-magnet-x:0px;--wiq-magnet-y:0px;position:relative;isolation:isolate;overflow:hidden}
.btn.wiq-primary-motion,.file-button.wiq-primary-motion{transform:translate3d(var(--wiq-magnet-x),var(--wiq-magnet-y),0)}
.btn.wiq-primary-motion:hover,.file-button.wiq-primary-motion:hover{transform:translate3d(var(--wiq-magnet-x),calc(var(--wiq-magnet-y) - 1px),0)}
.wiq-primary-motion:after{content:"";position:absolute;z-index:2;inset:-55% -35%;pointer-events:none;background:linear-gradient(108deg,transparent 37%,rgba(255,255,255,.17) 48%,transparent 59%);transform:translateX(-70%);opacity:0;transition:transform 460ms var(--wiq-ease-out),opacity 120ms ease}
.wiq-primary-motion:hover:after{transform:translateX(70%);opacity:1}
.card,.hero-card,.analysis-quality,.performance-stat{transition:border-color var(--wiq-motion-base) ease,transform var(--wiq-motion-base) var(--wiq-ease-out),box-shadow var(--wiq-motion-base) ease}
.card:hover{transform:none}

details>summary{transition:color var(--wiq-motion-fast) ease,background-color var(--wiq-motion-base) ease}
details[open]>summary{color:#fff}
details[open]>*:not(summary){animation:wiq-details-in var(--wiq-motion-base) var(--wiq-ease-out) both}
.correction-dialog[open]{animation:wiq-modal-in var(--wiq-motion-base) var(--wiq-ease-out) both}
.correction-dialog[open]::backdrop{animation:wiq-backdrop-in var(--wiq-motion-base) ease both}

/* Home and upload: keep the restored layout, add intentional interaction. */
body[data-page=home] .hero-copy>*{animation:wiq-copy-in var(--wiq-motion-slow) var(--wiq-ease-out) both;animation-delay:calc(var(--hero-order,0)*45ms)}
body[data-page=home] .hero-copy>.eyebrow{--hero-order:0}
body[data-page=home] .hero-copy>h1{--hero-order:1}
body[data-page=home] .hero-copy>p{--hero-order:2}
body[data-page=home] .hero-copy>.hero-actions{--hero-order:3}
body[data-page=home] .hero-copy>.fight-path{--hero-order:4}
body[data-page=home] .hero-copy>.trust-row{--hero-order:5}
.hero-card[data-upload-state=ready]{border-color:#4b83d4;box-shadow:0 24px 70px rgba(53,82,170,.24)}
.file-button.uploaded{animation:wiq-upload-ready var(--wiq-motion-base) var(--wiq-ease-impact)}
.file-button.uploaded>span{animation:wiq-upload-icon var(--wiq-motion-slow) var(--wiq-ease-impact)}
.upload-submit:not(:disabled){animation:wiq-submit-ready var(--wiq-motion-slow) var(--wiq-ease-out)}
.fight-path i{transform-origin:left;animation:wiq-path-grow 600ms var(--wiq-ease-out) both}
[data-motion-sequence=steps]>.step-card{will-change:opacity,transform}

/* Fighter selection feedback without changing the selection workflow. */
.select-stage{transition:border-color var(--wiq-motion-base) ease,box-shadow var(--wiq-motion-base) ease}
.select-stage[data-selection-state=drawing]{border-color:#4c6593}
.select-stage[data-selection-state=ready]{border-color:#4b917b;box-shadow:0 0 0 1px rgba(95,213,168,.12),0 22px 70px rgba(0,0,0,.28)}
.select-stage canvas{cursor:crosshair;touch-action:none}
.select-stage.selection-lock-flash{animation:wiq-lock-flash 420ms var(--wiq-ease-impact)}
.selection-impact{animation:wiq-selection-impact 280ms var(--wiq-ease-impact)}
.selection-status[data-state=ready]{border-color:#3d7b69;color:#8ee4c7}
.selection-status[data-state=warning]{border-color:#806331;color:#f1ca7f}
.target-options label:has(input:checked){transform:translateY(-1px);box-shadow:0 10px 24px rgba(65,83,164,.18)}

/* Immersive analysis page driven entirely by backend status values. */
.analysis-page{max-width:1120px;margin:58px auto 80px}
.analysis-header{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:30px;align-items:end;margin-bottom:26px}
.analysis-header h1{margin:10px 0 8px;font-size:clamp(42px,6vw,72px);line-height:.96}
.analysis-header p{max-width:720px;margin:0;color:#9eabc0;font-size:16px;line-height:1.65}
.analysis-live{display:flex;align-items:center;gap:9px;padding:9px 12px;border:1px solid #30476f;border-radius:99px;background:#0c172b;color:#cbd7ea;font-size:11px;font-weight:800;letter-spacing:.7px;text-transform:uppercase}
.analysis-live i{width:7px;height:7px;border-radius:50%;background:#5fe0b4;animation:wiq-live-pulse 1.5s ease-in-out infinite}
.analysis-layout{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(270px,.72fr);gap:18px;align-items:stretch}
.analysis-console{position:relative;overflow:hidden;min-height:570px;padding:30px;border:1px solid #334a75;border-radius:24px;background:linear-gradient(150deg,#101d36,#091326);box-shadow:0 28px 75px rgba(0,0,0,.32)}
.analysis-console:before{content:"";position:absolute;inset:0 0 auto;height:2px;background:linear-gradient(90deg,#4fd7ff,#7b84ff,transparent)}
.analysis-scoreboard{display:flex;align-items:flex-end;justify-content:space-between;gap:20px}
.analysis-scoreboard .big-progress{margin:0;font-variant-numeric:tabular-nums}
.analysis-scoreboard span{padding-bottom:10px;color:#8494ad;font-size:11px;font-weight:800;letter-spacing:1px;text-transform:uppercase}
.analysis-visual{position:relative;height:210px;margin:24px 0;overflow:hidden;border:1px solid #263c61;border-radius:18px;background:#07101f}
.analysis-visual:before{content:"";position:absolute;inset:50% 7% auto;height:1px;background:#304567}
.analysis-visual:after{content:"";position:absolute;top:-30%;bottom:-30%;width:32%;background:linear-gradient(90deg,transparent,rgba(103,132,255,.12),transparent);animation:wiq-analysis-scan 2.4s linear infinite}
.fighter-signal{position:absolute;top:32px;bottom:32px;width:32%;border:1px solid #314a78;border-radius:48% 48% 16px 16px;background:linear-gradient(180deg,rgba(86,126,214,.15),rgba(16,31,58,.2))}
.fighter-signal:before{content:"";position:absolute;top:14px;left:50%;width:34px;height:34px;border:2px solid currentColor;border-radius:50%;transform:translateX(-50%)}
.fighter-signal:after{content:"";position:absolute;top:56px;left:50%;width:2px;height:72px;background:currentColor;box-shadow:-20px 28px 0 -1px currentColor,20px 28px 0 -1px currentColor;transform:translateX(-50%)}
.fighter-signal.a{left:11%;color:#62aaff}
.fighter-signal.b{right:11%;color:#e2b85f}
.fighter-signal span{position:absolute;inset:auto 0 9px;text-align:center;color:currentColor;font-size:11px;font-weight:900;letter-spacing:1px}
.analysis-progress{height:12px;border:1px solid #294266;border-radius:99px;background:#07101f}
.analysis-progress .progress-bar{position:relative;overflow:hidden;transition:width 650ms var(--wiq-ease-out)}
.analysis-progress .progress-bar:after{content:"";position:absolute;inset:0;background:linear-gradient(100deg,transparent,rgba(255,255,255,.4),transparent);animation:wiq-progress-sheen 1.8s linear infinite}
.analysis-message{min-height:48px;margin:17px 0 5px;color:#dce5f4;font-size:15px;font-weight:750}
.analysis-metrics{grid-template-columns:repeat(4,minmax(0,1fr));margin-top:20px}
.analysis-metrics .value{font-variant-numeric:tabular-nums}
.analysis-stages{padding:22px;border:1px solid #2b3f63;border-radius:22px;background:#0b1528}
.analysis-stages h2{margin:3px 0 18px;font-size:20px}
.analysis-stages ol{display:grid;gap:2px;margin:0;padding:0;list-style:none}
.analysis-stage{position:relative;display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:center;min-height:51px;padding:7px 8px;border-radius:11px;color:#77869f;transition:color var(--wiq-motion-base) ease,background-color var(--wiq-motion-base) ease,transform var(--wiq-motion-base) var(--wiq-ease-out)}
.analysis-stage i{display:grid;place-items:center;width:24px;height:24px;border:1px solid #34496d;border-radius:50%;font-style:normal;font-size:11px;font-weight:900}
.analysis-stage span{display:flex;flex-direction:column;font-size:12px;font-weight:800}
.analysis-stage small{margin-top:2px;color:#718098;font-size:11px;font-weight:500}
.analysis-stage[data-state=active]{color:#fff;background:#14213b;transform:translateX(3px)}
.analysis-stage[data-state=active] i{border-color:#7690ff;color:#9edaff;animation:wiq-stage-pulse 1.2s ease-in-out infinite}
.analysis-stage[data-state=done]{color:#aadfce}
.analysis-stage[data-state=done] i{border-color:#407864;background:#143128;color:#6fe1ba}
.analysis-stage[data-state=done] i:before{content:"✓"}.analysis-stage[data-state=done] i{font-size:0}.analysis-stage[data-state=done] i:before{font-size:11px}
.analysis-stage[data-state=error]{color:#ff9eac;background:#321722}
.analysis-stage-note{margin:15px 4px 0;color:#74829a;font-size:11px;line-height:1.55}
.analysis-page.analysis-complete .analysis-console{border-color:#3f7b68;animation:wiq-complete 420ms var(--wiq-ease-impact)}
.analysis-page.analysis-error .analysis-console{border-color:#87455a;animation:wiq-error 360ms ease}
.analysis-page.analysis-complete .analysis-live i{animation:none}

/* Results: dense sports analytics, clearer section transitions. */
body[data-page=result] main{position:relative;padding-bottom:24px}
body[data-page=result] .section-title:first-child{min-height:150px;align-items:center;margin:24px 0 18px;padding:24px 0;border-bottom:1px solid #263958}
body[data-page=result] .section-title:first-child h2{font-size:clamp(40px,6vw,68px);margin:4px 0}
body[data-page=result] .report-path{position:sticky;z-index:35;top:92px;box-shadow:0 16px 35px rgba(0,0,0,.18);transition:border-color var(--wiq-motion-base) ease,box-shadow var(--wiq-motion-base) ease}
body[data-page=result] .report-path a[aria-current=true]{border-color:#7183d6;background:#1b2d50;color:#fff;transform:translateY(-1px)}
body[data-page=result] .analysis-quality-grid strong,body[data-page=result] .performance-stat>strong,body[data-page=result] .metric .value,body[data-page=result] .score{font-variant-numeric:tabular-nums}
body[data-page=result] .performance-stat.is-stat-impact,body[data-page=result] .metric.is-stat-impact{animation:wiq-stat-impact 360ms var(--wiq-ease-impact)}
.live-stat-grid>div.is-stat-impact{animation:wiq-stat-impact 300ms var(--wiq-ease-impact)}
.live-event-item.is-new button{animation:wiq-event-emphasis 680ms var(--wiq-ease-out)}
body[data-page=result] .report-details[open],body[data-page=result] .report-technical[open]{border-color:#425984}
body[data-page=result] table tbody tr{transition:background-color var(--wiq-motion-fast) ease}
body[data-page=result] table tbody tr:hover{background:rgba(105,127,204,.07)}
body[data-page=result] .attack-mix b{transform:scaleX(0);transform-origin:left;transition:transform 720ms var(--wiq-ease-out)}
body[data-page=result] .tactical-performance.is-visible .attack-mix b{transform:scaleX(1)}
body[data-page=result] .comparison-table .is-better{transition:color var(--wiq-motion-base) ease,text-shadow var(--wiq-motion-base) ease}
body[data-page=result] .comparison-table .is-better[data-wiq-counted=true]{text-shadow:0 0 18px rgba(95,213,168,.16)}

@keyframes wiq-page-enter{from{opacity:.78;transform:translateY(3px)}to{opacity:1;transform:none}}
@keyframes wiq-copy-in{from{opacity:.2;transform:translateY(9px)}to{opacity:1;transform:none}}
@keyframes wiq-menu-in{from{opacity:0;transform:translateY(-7px) scaleY(.96)}to{opacity:1;transform:none}}
@keyframes wiq-details-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@keyframes wiq-modal-in{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}
@keyframes wiq-backdrop-in{from{opacity:0}to{opacity:1}}
@keyframes wiq-upload-ready{0%{transform:scale(.985)}65%{transform:scale(1.01)}100%{transform:none}}
@keyframes wiq-upload-icon{0%{transform:translateY(5px);opacity:.3}100%{transform:none;opacity:1}}
@keyframes wiq-submit-ready{from{opacity:.5;transform:translateY(4px)}to{opacity:1;transform:none}}
@keyframes wiq-path-grow{from{transform:scaleX(0);opacity:0}to{transform:scaleX(1);opacity:1}}
@keyframes wiq-selection-impact{0%{transform:scale(.997)}60%{transform:scale(1.002)}100%{transform:none}}
@keyframes wiq-lock-flash{0%{box-shadow:0 0 0 0 rgba(95,213,168,0)}45%{box-shadow:0 0 0 3px rgba(95,213,168,.18),0 22px 70px rgba(0,0,0,.28)}100%{box-shadow:0 0 0 1px rgba(95,213,168,.12),0 22px 70px rgba(0,0,0,.28)}}
@keyframes wiq-live-pulse{0%,100%{opacity:.45;transform:scale(.85)}50%{opacity:1;transform:scale(1.12)}}
@keyframes wiq-analysis-scan{from{left:-36%}to{left:110%}}
@keyframes wiq-progress-sheen{from{transform:translateX(-130%)}to{transform:translateX(150%)}}
@keyframes wiq-stage-pulse{0%,100%{transform:scale(.92);opacity:.68}50%{transform:scale(1.04);opacity:1}}
@keyframes wiq-complete{0%{transform:scale(.995)}65%{transform:scale(1.004)}100%{transform:none}}
@keyframes wiq-error{0%,100%{transform:translateX(0)}35%{transform:translateX(-3px)}70%{transform:translateX(3px)}}
@keyframes wiq-stat-impact{0%{transform:scale(.98)}60%{transform:scale(1.015)}100%{transform:none}}
@keyframes wiq-event-emphasis{0%,100%{box-shadow:none}38%{border-color:rgba(92,158,255,.62);box-shadow:0 8px 30px rgba(38,91,177,.18)}}

@media(max-width:900px){
  .analysis-layout{grid-template-columns:1fr}.analysis-stages ol{grid-template-columns:1fr 1fr}.analysis-stage-note{grid-column:1/-1}
  body[data-page=result] .report-path{top:82px}
}
@media(max-width:620px){
  .analysis-page{margin:36px auto 60px}.analysis-header{grid-template-columns:1fr}.analysis-live{justify-self:start}.analysis-console{min-height:0;padding:21px}.analysis-visual{height:175px}.analysis-metrics{grid-template-columns:1fr 1fr}.analysis-stages{padding:17px}.analysis-stages ol{grid-template-columns:1fr}.analysis-stage{min-height:46px}
  body[data-page=result] .section-title:first-child{min-height:0;align-items:flex-start;flex-direction:column;padding:16px 0}
  body[data-page=result] .report-path{top:72px}
}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto!important}
  *,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.001ms!important}
  body.motion-enabled .wiq-reveal{opacity:1!important;transform:none!important}
  .wiq-primary-motion{--wiq-magnet-x:0px!important;--wiq-magnet-y:0px!important;transform:none!important}
  .wiq-primary-motion:after{display:none!important}
  .page-scroll-progress{display:none}
}

/* redesign.css */
/* ===========================================================================
   WarriorIQ visual system - broadcast graphics for an analysis tool.

   The previous look was a blue-violet gradient wash behind glowing, heavily
   rounded cards, with the headline set in gradient text. It read as a template.

   Three decisions drive everything here.

   1. The chrome carries no brand hue. Canvas, panels, type and rules are all
      neutral graphite. Colour is spent only on the sport a fight belongs to and
      on status - which is what makes five sports read as one product rather
      than five themes fighting each other.
   2. Depth comes from hairlines and type weight, never from coloured glow.
      A 1px rule at the right value separates two surfaces more convincingly
      than a 55px shadow, and it survives on a cheap panel.
   3. Corners are nearly square. 19px radius reads as a consumer app; 3-6px
      reads as an instrument.

   Loaded last so it settles the argument with the older surface layers.
   =========================================================================== */

/* --- Canvas --------------------------------------------------------------- */
html, body { background: var(--wiq-canvas); }

/* --- Structure ------------------------------------------------------------
   A single measure for the whole product, and generous air around it. The old
   1280px shell with 36px gutters made every page feel like a settings screen. */
.shell { width: min(1180px, calc(100% - 48px)); }

/* --- Navigation -----------------------------------------------------------
   A rule under the bar instead of a floating translucent panel, so the header
   reads as part of the page rather than hovering over it. */
.nav {
  height: 68px;
  border-bottom: 1px solid var(--wiq-line-soft);
}

.brand { font-size: 19px; font-weight: 800; letter-spacing: -.03em; }
.brand span { color: var(--wiq-text); }          /* the logo carries the colour */
.brand-mark { display: none; }

.navlinks a {
  padding: 8px 11px;
  border-radius: 3px;
  color: var(--wiq-text-tertiary);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .002em;
}
.navlinks a:hover { background: transparent; color: var(--wiq-text); }
.navlinks a[aria-current="page"] { color: var(--wiq-text); }

/* --- Buttons --------------------------------------------------------------
   One loud button per screen. Solid white on graphite is the highest contrast
   available and needs no glow to be found; everything else is a hairline ghost. */
.btn {
  border-radius: 3px;
  padding: 11px 18px;
  background: #f5f5f6;
  color: #0a0a0b;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .004em;
  box-shadow: none;
  transition: background-color 140ms var(--wiq-motion-ease, ease),
              border-color 140ms var(--wiq-motion-ease, ease);
}
.btn:hover { background: #ffffff; transform: none; filter: none; }

.btn.secondary, .nav-cta {
  background: transparent;
  border: 1px solid var(--wiq-line) !important;
  color: var(--wiq-text) !important;
}
.btn.secondary:hover { background: rgba(255, 255, 255, .04); border-color: #3a3a40 !important; }

.btn.danger { background: transparent; border: 1px solid #5b2b33; color: #ff9aa8; }
.nav-signup { background: #f5f5f6; color: #0a0a0b; }

/* --- Surfaces -------------------------------------------------------------
   Cards stop being the default container. Where one is still a card it is a
   flat panel with a hairline, not a lifted, glowing, rounded box. */
.card, .hero-card, .setup-card, .stat-band, .sport-card, .empty-workspace {
  border-radius: 4px;
  background: var(--wiq-canvas-raised);
  border: 1px solid var(--wiq-line-soft);
  box-shadow: none;
}
.card:hover { border-color: var(--wiq-line-soft); }

/* --- Type -----------------------------------------------------------------
   Tighter, heavier, and never in a gradient. The headline is the loudest thing
   on the page because it is large and solid, not because it glows. */
h1, h2, h3 { letter-spacing: -.03em; }
.hero h1 {
  font-size: clamp(44px, 6.2vw, 82px);
  line-height: .94;
  letter-spacing: -.045em;
  font-weight: 800;
}
.hero h1 em {
  font-style: normal;
  color: var(--wiq-text-tertiary);
  -webkit-text-stroke: 0;
}
.hero h1 span { color: var(--wiq-text); }

.eyebrow { color: var(--wiq-text-tertiary); }
.eyebrow::before { background: var(--wiq-text-tertiary); }

/* --- Hero -----------------------------------------------------------------
   Left aligned and set against a rule. Centring made a product page read as a
   landing page for something that does not exist yet. */
.hero-centered { text-align: left; padding: clamp(64px, 12vh, 132px) 0 clamp(52px, 9vh, 96px); }
.hero-centered .hero-copy { align-items: flex-start; margin: 0; max-width: 780px; }
.hero-centered .hero-actions,
.hero-centered .fight-path,
.hero-centered .trust-row,
.hero-centered .sport-rail { justify-content: flex-start; }
.hero-centered .hero-copy > p { margin-inline: 0; font-size: 17px; color: var(--wiq-text-secondary); }
.hero-centered .eyebrow::before { display: inline-block; }

.btn-lead { min-height: 48px; padding-inline: 24px; font-size: 14px; }

/* The sport rail becomes a measured strip against a rule, not a row of words. */
.sport-rail {
  gap: 0;
  margin-top: 34px;
  padding-top: 18px;
  border-top: 1px solid var(--wiq-line-soft);
  width: 100%;
}
.sport-rail b {
  padding-right: 22px;
  color: var(--wiq-text-secondary);
  font-size: 13px;
  font-weight: 600;
}
.sport-rail b + b::before { display: none; }

/* --- Sport chooser --------------------------------------------------------
   The five cards are the page. Square, flat, and separated by rules; the sport
   only shows its colour on the crest and on hover. */
.sport-card {
  gap: 8px;
  padding: 26px 24px 24px;
  border-radius: 4px;
  background: var(--wiq-canvas-raised);
  transition: background-color 140ms ease, border-color 140ms ease;
}
.sport-card:hover { transform: none; background: #141416; border-color: var(--wiq-line); }
.sport-card-mark { display: none; }             /* the radial wash goes */
.sport-crest { border-radius: 3px; }
.sport-card h2 { font-size: 22px; font-weight: 750; }

/* --- Statistics -----------------------------------------------------------
   Numbers are the product. They get size, tabular figures and a rule above,
   and they are not put inside boxes. */
.stat-band { border-radius: 4px; }
.stat-support { border-radius: 3px; gap: 1px; background: var(--wiq-line-soft); border-color: var(--wiq-line-soft); }
.stat { background: var(--wiq-canvas-raised); }
.stat-lead strong { letter-spacing: -.05em; font-weight: 800; }

.metric {
  border-radius: 3px;
  border-color: var(--wiq-line-soft);
  background: var(--wiq-canvas-raised);
}
.metric .value { letter-spacing: -.04em; font-weight: 800; }
.score { color: var(--wiq-text); letter-spacing: -.05em; }

/* --- Tables ---------------------------------------------------------------
   A real table: ruled rows, tabular figures, a quiet header. */
table { border-collapse: collapse; }
th {
  padding: 10px 12px;
  border-bottom: 1px solid var(--wiq-line);
  color: var(--wiq-text-tertiary);
  background: transparent;
}
td { padding: 12px; border-bottom: 1px solid var(--wiq-line-soft); }
tbody tr:hover td { background: rgba(255, 255, 255, .02); }

/* --- Inputs ---------------------------------------------------------------
   Square fields on the panel colour, with the focus ring doing the work. */
.field input, .field select, .field textarea {
  border-radius: 3px;
  border-color: var(--wiq-line);
  background-color: #0d0d0f;
  padding: 11px 12px;
}

/* Restated after the colour so the chevron keeps its geometry whatever else
   touches the background. */
.field select {
  background-repeat: no-repeat;
  background-position: right 15px center;
  background-size: 11px 8px;
  padding-right: 40px;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: #4a4a52;
  box-shadow: none;
}

.pill {
  border-radius: 3px;
  border-color: var(--wiq-line);
  background: transparent;
  color: var(--wiq-text-secondary);
}

/* --- Notices --------------------------------------------------------------
   A left rule and flat ground rather than a tinted rounded box. */
.notice {
  border-radius: 0 3px 3px 0;
  border: 1px solid var(--wiq-line-soft);
  border-left: 2px solid var(--wiq-line);
  background: var(--wiq-canvas-raised);
  color: var(--wiq-text-secondary);
}

/* --- Footer --------------------------------------------------------------- */
.footer { border-top: 1px solid var(--wiq-line-soft); }

/* --- Responsive -----------------------------------------------------------
   The measure tightens before the layout collapses, so the tablet width is a
   designed state rather than a squeezed desktop. */
@media (max-width: 1024px) {
  .shell { width: min(100%, calc(100% - 40px)); }
}

@media (max-width: 620px) {
  .shell { width: calc(100% - 32px); }
  .nav { height: 60px; }
  .hero-centered { padding: 44px 0 36px; }
  .hero h1 { font-size: 40px; letter-spacing: -.035em; }
  .hero-centered .hero-copy > p { font-size: 15px; }
  .btn { width: auto; }
  .sport-rail { display: flex; flex-wrap: wrap; row-gap: 6px; }
  .sport-rail b { padding-right: 16px; font-size: 12px; }
}

/* --- Gradient text, removed -----------------------------------------------
   The display lines were painted with a clipped linear-gradient. Setting a
   colour does not undo that: the fill has to be reset too, or the gradient
   keeps showing through. A headline earns attention by size and weight. */
.hero h1 em,
.pricing-hero h1 em,
.workflow-heading h1 em,
.archive-hero h1 em,
h1 em, h2 em {
  background: none !important;
  -webkit-background-clip: border-box !important;
  background-clip: border-box !important;
  -webkit-text-fill-color: currentColor !important;
  color: var(--wiq-text-tertiary) !important;
}

/* Decorative glow blobs behind the hero and cards. */
.hero-copy::before,
.hero-card::before,
.pricing-hero::before { display: none !important; }

.hero-card, .card, .pricing-card {
  background: var(--wiq-canvas-raised) !important;
  box-shadow: none !important;
}

/* --- The three-step path --------------------------------------------------
   Numbered chips in brand blue were the only colour left in the chrome. They
   become quiet counters against a rule, which is what they are. */
.fight-path { gap: 0; color: var(--wiq-text-tertiary); font-size: 13px; }
.fight-path span { display: inline-flex; align-items: center; gap: 9px; padding-right: 26px; }
.fight-path b {
  width: auto;
  height: auto;
  padding: 0;
  border-radius: 0;
  background: none;
  color: var(--wiq-text-tertiary);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.fight-path i { display: none; }

.status-dot { box-shadow: none; }

/* --- Remaining colour leaks ------------------------------------------------
   A blue glow was reapplied to primary buttons by the motion layer, and two
   decorative washes survived on section backgrounds. The chrome carries no hue,
   so they go; the button is already the highest-contrast element on the page. */
.btn, .btn:hover, .nav-signup, .wiq-primary-motion { box-shadow: none !important; }

.coach-callout, .final-cta, .trust-panel, .product-preview {
  background-image: none !important;
  background-color: transparent;
}

/* Section rules replace section tints: a hairline says "new section" without
   painting a coloured field behind it. */
.product-section, .trust-panel {
  border-top: 1px solid var(--wiq-line-soft);
  padding-top: clamp(48px, 7vh, 84px);
}

.final-cta {
  border: 1px solid var(--wiq-line-soft);
  border-radius: 4px;
  padding: clamp(28px, 4vw, 44px);
}

/* The preview mock keeps its two fighter colours - that is data, not chrome. */
.preview-screen { border-color: var(--wiq-line-soft); box-shadow: none; background: var(--wiq-canvas-raised); }
.preview-fight-stage { background: #0d0d0f; border-color: var(--wiq-line-soft); }
.preview-scan { display: none; }

/* --- Upload target --------------------------------------------------------
   The primary action on a sport's page, so it wears that sport rather than a
   brand blue that belongs to nothing. Square, ruled, and quiet until it has a
   file - the dashed edge already says "drop something here". */
.file-button {
  border-radius: 4px;
  border: 1px dashed var(--wiq-line);
  background: transparent;
  color: var(--wiq-text) !important;
  min-height: 96px;
  flex-direction: column;
  gap: 4px;
}
.file-button:hover {
  transform: none;
  border-color: rgb(var(--sport-accent) / .55);
  background: rgb(var(--sport-accent) / .05);
}
.file-button span {
  color: rgb(var(--sport-accent-soft));
  background: none;
  font-size: 18px;
}
.file-button b { font-size: 14px; font-weight: 700; }
.file-button small { color: var(--wiq-text-tertiary); }
.file-button.uploaded { border-style: solid; border-color: rgb(var(--sport-accent) / .5); }

.console-badge {
  border-radius: 3px;
  border: 1px solid var(--wiq-line);
  background: transparent;
  color: var(--wiq-text-secondary);
}

/* The step eyebrow on a sport page carries the sport, which is the only place
   colour is doing identification rather than decoration. */
.setup-head .eyebrow { color: rgb(var(--sport-accent-soft)); }
.setup-head .eyebrow::before { background: rgb(var(--sport-accent)); }

.upload-progress span { border-radius: 2px; background: var(--wiq-line-soft); }
.upload-progress i { background: rgb(var(--sport-accent)); border-radius: 2px; }

/* --- Last of the navy -----------------------------------------------------
   The header still painted itself a translucent blue-black, and the upload
   target's dashed edge was set by a more specific rule than the one above, so
   both kept the old palette against the new canvas.

   Transparent was the wrong cure. The bar is sticky, so the page scrolled
   visibly underneath it and headings slid through the logo. It needs to be
   opaque and the same colour as the canvas - the old navy goes, the solidity
   stays. */
.nav, .site-header, header.nav {
  background: var(--wiq-canvas) !important;
  backdrop-filter: none;
}

.upload-field .file-button,
.field .file-button,
.file-button { border-color: var(--wiq-line) !important; }

.upload-field .file-button:hover,
.field .file-button:hover,
.file-button:hover { border-color: rgb(var(--sport-accent) / .6) !important; }

.file-button.uploaded { border-color: rgb(var(--sport-accent) / .55) !important; }

/* The toast and cookie notice share the neutral chrome. */
.app-toast, .cookie-notice {
  border-radius: 4px;
  border-color: var(--wiq-line);
  background: var(--wiq-canvas-raised);
  backdrop-filter: none;
  box-shadow: none;
}

/* Keep the page clear of the fixed cookie notice at every width.

   Measured on the live site with the notice showing and the page scrolled
   fully down: at 1280x800 the notice covers **every legal link the site has** -
   Terms, Privacy, Cookies, Video Upload Policy, Refunds & Withdrawal,
   Acceptable Use and Contact - and at 375x812 it covers those plus the
   copyright line. A consent banner that hides the cookie policy behind itself
   is the one thing it must not do, and until the visitor answers it there is
   no way to read what they are answering about.

   There was already a rule for this, but it padded `main`. The footer is
   main's sibling, so it never moved. The mobile override lives with the
   notice's own max-height cap further down this file. */
body:has(.cookie-notice:not([hidden])) { padding-bottom: 180px; }

/* ===========================================================================
   Depth, second pass.

   Stripping the gradient wash was right; replacing it with nothing was not.
   Flat grey on flat black reads as unstyled, not restrained. A dark interface
   earns its quality from three things the last pass left out: a real step
   between surfaces, a lit top edge so a panel looks like an object rather than
   a hole, and one accent used with conviction instead of none at all.
   =========================================================================== */

:root {
  /* Championship gold. Warm against a cold canvas, distinct from all five
     sport accents (blue, red, orange, cyan, violet), and it reads as sport
     rather than software. Used on one thing per screen. */
  --wiq-accent: 214 176 96;
}

/* Panels become objects: a lit top edge, a real fill, and a hairline that is
   actually visible against the canvas. */
.card, .hero-card, .setup-card, .stat-band, .sport-card,
.empty-workspace, .pricing-card, .preview-screen {
  background: var(--wiq-canvas-raised) !important;
  border: 1px solid var(--wiq-line-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .045) !important;
}

.sport-card:hover, .card:hover {
  border-color: var(--wiq-line);
  background: var(--wiq-panel) !important;
}

/* --- The accent, used sparingly -------------------------------------------
   The eyebrow above a section title and the active nav item. That is the whole
   budget; anything more and it stops meaning "look here". */
.eyebrow { color: rgb(var(--wiq-accent)); }
.eyebrow::before { background: rgb(var(--wiq-accent)); width: 22px; height: 2px; }

.navlinks a[aria-current="page"] {
  color: var(--wiq-text);
  box-shadow: inset 0 -2px 0 rgb(var(--wiq-accent));
  border-radius: 0;
}

/* The primary button keeps white for contrast, but gains a warm edge so it
   belongs to the palette instead of floating on top of it. */
.btn { box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25) !important; }

/* --- Rhythm ---------------------------------------------------------------
   Section spacing was uniform, so every band had the same weight. The hero
   breathes, sections settle, and the gap between a heading and its content is
   deliberately tighter than the gap between sections. */
.product-section { padding-top: clamp(56px, 8vh, 104px); }
.section-intro { max-width: 620px; margin-bottom: clamp(24px, 4vh, 40px); }
.section-intro h2 { margin: 10px 0 12px; font-size: clamp(26px, 3.4vw, 40px); }
.section-intro p { color: var(--wiq-text-secondary); line-height: 1.65; }

/* --- Section titles -------------------------------------------------------
   A rule under the heading row gives each section a top edge without boxing it. */
.section-title {
  padding-bottom: 16px;
  border-bottom: 1px solid var(--wiq-line-soft);
  margin-bottom: 22px;
}

/* --- Hero, given something to look at -------------------------------------
   Moving the upload card to the sport pages left the hero as type alone on
   black, which is why the page read as unfinished. The product illustration
   moves up beside the headline: the hero now shows what WarriorIQ does instead
   of only asserting it, and the two columns give the page a centre of gravity.
   --------------------------------------------------------------------------- */
@media (min-width: 981px) {
  .hero-centered { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .92fr); gap: 64px; align-items: center; }
  .hero-centered .hero-copy { max-width: none; }
  /* The illustration is pulled out of the section below and parked in the
     hero's second column, so no markup has to move. */
  .product-preview { grid-column: 2; grid-row: 1; padding-top: 0; border-top: 0; }
  .product-preview .preview-copy { display: none; }
  .hero-centered + .product-preview { display: none; }
}

/* The mock itself: a real instrument panel rather than two empty outlines. */
.preview-screen { padding: 14px; border-radius: 5px; }
.preview-screen-head { color: var(--wiq-text-tertiary); }
.preview-screen-head b { color: rgb(var(--wiq-accent)); }
.preview-fight-stage {
  background: linear-gradient(180deg, #101014, #0b0b0d);
  border-color: var(--wiq-line-soft);
  aspect-ratio: 16 / 9.6;
}
.preview-fighter { border-width: 1.5px; border-radius: 3px; }
.preview-timeline i { background: rgb(var(--wiq-accent)); }
.preview-timeline span { border-radius: 2px; }

/* The illustration has to fill the column it was given, or it reads as a
   thumbnail floating in empty space rather than the hero's second half. */
.product-preview { display: block; width: 100%; }
.preview-visual { width: 100%; max-width: none; }
.preview-screen { width: 100%; }

/* Its header row was sized for a wider band and wrapped into four words. */
.preview-screen-head {
  gap: 12px;
  flex-wrap: nowrap;
  white-space: nowrap;
  font-size: var(--wiq-text-micro);
  letter-spacing: .07em;
}

.preview-fighter { font-size: clamp(14px, 2.4vw, 26px); }

/* --- Keyboard review ------------------------------------------------------
   Building a training set means judging a thousand candidates, so the active
   one has to be obvious at a glance and the shortcuts have to be visible
   rather than folklore. */
.review-keys {
  display: flex;
  gap: 8px 20px;
  flex-wrap: wrap;
  margin: 0 0 18px;
  padding: 12px 14px;
  border: 1px solid var(--wiq-line-soft);
  border-radius: 4px;
  background: var(--wiq-canvas-raised);
  color: var(--wiq-text-tertiary);
  font-size: var(--wiq-text-xs);
}

.review-keys kbd {
  display: inline-block;
  min-width: 20px;
  margin-right: 4px;
  padding: 2px 6px;
  border: 1px solid var(--wiq-line);
  border-bottom-width: 2px;
  border-radius: 3px;
  background: var(--wiq-panel);
  color: var(--wiq-text);
  font: 600 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* The candidate under the cursor is marked on the accent, not by a colour
   change to the whole card, so a reviewed card still reads as reviewed. */
.review-candidate { border-left: 2px solid transparent; }
.review-candidate.is-active {
  border-left-color: rgb(var(--wiq-accent));
  background: var(--wiq-panel) !important;
}
.review-candidate.reviewed { opacity: .62; }
.review-candidate.reviewed.is-active { opacity: 1; }

/* --- Fight vitals ---------------------------------------------------------
   The report used to collapse to almost nothing whenever the action model was
   untrusted, which is every fight until it is trained. These six come from
   pose geometry and are always real, so they lead: number first at display
   size, one word under it, and a short plain sentence only if you want it.
   A fighter should get the whole row in about five seconds.
   --------------------------------------------------------------------------- */
.fight-vitals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  margin: clamp(20px, 3vh, 32px) 0 0;
  border: 1px solid var(--wiq-line-soft);
  border-radius: 4px;
  background: var(--wiq-line-soft);
  overflow: hidden;
}

.fight-vitals article {
  display: grid;
  gap: 2px;
  padding: 20px 18px 18px;
  background: var(--wiq-canvas-raised);
}

.fight-vitals b {
  color: var(--wiq-text);
  font-size: clamp(34px, 4.4vw, 46px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.045em;
}

/* The unit sits back so the figure carries the row. */
.fight-vitals b em {
  font-style: normal;
  font-size: .44em;
  font-weight: 650;
  color: var(--wiq-text-tertiary);
  margin-left: .04em;
}

.fight-vitals span {
  margin-top: 6px;
  color: var(--wiq-text);
  font-size: var(--wiq-text-sm);
  font-weight: 700;
}

.fight-vitals small {
  color: var(--wiq-text-tertiary);
  font-size: var(--wiq-text-micro);
  line-height: 1.45;
}

.vitals-note {
  margin: 14px 0 0;
  padding: 12px 14px;
  max-width: 70ch;
  border: 1px solid var(--wiq-line-soft);
  border-left: 2px solid var(--wiq-warning);
  border-radius: 0 3px 3px 0;
  background: var(--wiq-canvas-raised);
  color: var(--wiq-text-secondary);
  font-size: var(--wiq-text-sm);
  line-height: 1.6;
}

@media (max-width: 620px) {
  .fight-vitals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fight-vitals b { font-size: 32px; }
  .fight-vitals article { padding: 16px 14px; }
}

/* --- The one genuinely advanced setting ----------------------------------
   Collapsed, because it needs a key for an outside service and almost no
   fight needs it. Fight format stays open: getting the rounds wrong segments
   the analysis wrongly, so that one is not something to tuck away. */
.setup-extra {
  margin: 4px 0 14px;
  border: 1px solid var(--wiq-line-soft);
  border-radius: 4px;
  background: var(--wiq-canvas-raised);
}
.setup-extra > summary {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 13px 15px;
  cursor: pointer;
  list-style: none;
}
.setup-extra > summary::-webkit-details-marker { display: none; }
.setup-extra > summary::after { content: "+"; margin-left: auto; color: var(--wiq-text-tertiary); }
.setup-extra[open] > summary::after { content: "\2212"; }
.setup-extra > summary strong { color: var(--wiq-text); font-size: var(--wiq-text-sm); font-weight: 650; }
.setup-extra > summary small { color: var(--wiq-text-tertiary); font-size: var(--wiq-text-micro); }
.setup-extra > .check { display: block; padding: 0 15px 15px; }

/* The consent notice is required, but on a phone it was covering the upload
   button - the one thing the page exists to offer. Cap it to a slim bar at the
   very bottom so the primary action stays reachable, and keep the three
   choices on one row so "Reject Non-Essential" is exactly as easy as "Accept
   All". Nothing is removed; it simply stops being a half-screen wall. */
@media (max-width: 560px) {
  .cookie-notice {
    bottom: 8px;
    padding: 10px 12px;
    gap: 8px;
    max-height: 42vh;
    overflow-y: auto;
  }
  .cookie-notice p { font-size: 11px; line-height: 1.4; }
  .cookie-notice .btn { padding: 9px 4px; font-size: 11px; }
  /* Reserve room underneath the page for the fixed notice. Without this the
     upload button - the one control the page exists to offer - sat behind the
     banner on a 375px screen and could not be reached at all.

     Padded on the body, not on main. The footer is main's sibling, so padding
     main moved the upload button clear and left the footer exactly where it
     was: measured on the live site at 375x812, scrolled fully to the bottom,
     the notice covered the last 150px - which is every legal link the site
     has (Terms, Privacy, **Cookies**, Video Upload Policy, Refunds &
     Withdrawal, Acceptable Use, Contact) and the copyright line. A cookie
     banner that hides the cookie policy is the one thing it must never do.

     Sized from the notice's own cap above rather than a round number, so the
     two cannot drift apart. */
  body:has(.cookie-notice:not([hidden])) { padding-bottom: calc(42vh + 24px); }
}

/* --- Social sign-in -------------------------------------------------------
   Was a two-column grid with hardcoded blues, so a single Google button sat
   half-width in the wrong palette. One column, and the same geometry as the
   email and password fields directly below it, so the card reads as one form
   rather than two. Content stays left-aligned with the icon. */
.social-auth-grid { grid-template-columns: 1fr; gap: 8px; }

.social-auth-button {
  width: 100%;
  min-height: var(--wiq-control-height, 44px);
  justify-content: flex-start;
  gap: 12px;
  padding: 11px 12px;
  border-radius: 3px;
  border: 1px solid var(--wiq-line);
  background: var(--wiq-panel);
  color: var(--wiq-text);
  font-size: var(--wiq-text-sm);
  font-weight: 650;
}
.social-auth-button:hover:not(:disabled) {
  border-color: #4a4a52;
  background: var(--wiq-canvas-raised);
  transform: none;                 /* the lift fought the square field styling */
}
/* The consent box is enforced on click, not by disabling: a greyed-out button
   reads as broken, and the reason it cannot be used is out of view. */
/* The gate is the reason the buttons above are disabled, so it is visible
   from the start rather than after a press that already failed. */
.social-auth-button[disabled] { opacity: .45; cursor: not-allowed; }
.social-auth-button[disabled]:hover { transform: none; }
.check.needs-attention,
fieldset.needs-attention {
  border-radius: 3px;
  box-shadow: 0 0 0 2px var(--wiq-warning);
  transition: box-shadow 160ms var(--wiq-motion-ease, ease);
}

.social-auth-gate {
  margin: 8px 0 0;
  color: var(--wiq-text-tertiary);
  font-size: var(--wiq-text-xs);
}

/* Recovery line for a provider that no longer has a button: "Signed up with
   GitHub? Use that to sign in."
   It has to be a <button>, because starting a social sign-in is a form POST
   carrying a CSRF token - an <a> cannot do it. So the button is reset back to
   looking like the sentence it sits in. Without this it renders as a native
   control: measured grey 240,240,240 with a 2px border in the middle of a line
   of prose. The existing reset is scoped to .assign-note and does not reach
   here. */
.social-auth-legacy {
  margin: 10px 0 0;
  color: var(--wiq-text-tertiary);
  font-size: var(--wiq-text-xs);
}

.social-auth-legacy .text-link {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: #7fb1ff;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* The score line is not the headline while strike scoring is untrained. It
   said "Withheld" in the largest type on the page, so the most prominent thing
   in a fighter's report was a refusal. */
.result-scoreline .score-muted {
  font-size: var(--wiq-text-lg, 20px);
  color: var(--wiq-text-tertiary);
  font-weight: 600;
}

/* a11y.css */
/* ============================================================================
   Tap targets and control sizing
   ----------------------------------------------------------------------------
   Last in the shell bundle on purpose. These are floor values that have to win
   over whatever a component set, and being loaded last is how they do that
   without a single !important - see CSS_BUNDLES in app/main.py.

   Three measured problems, all on the upload form, which is the one form a
   first-time user has to complete:

     * selects rendered at 15px. iOS Safari zooms the whole page when a control
       under 16px is focused, and it does not zoom back out. 16px is the
       documented threshold, not a rounded-up guess.
     * the consent checkbox was 13x13 with a label row 17-20px tall, and it is
       REQUIRED to proceed. 44px is the WCAG 2.5.5 / Apple HIG target.
     * footer links were 19px tall.

   Nothing here changes a colour, a font family or a layout - only the size of
   the things a finger has to hit and the text inside controls.
   ========================================================================= */

/* --- 16px floor on anything typed into or picked from ------------------- */
input,
select,
textarea {
  font-size: max(16px, 1em);
}

/* A file input's own font-size drives the height of its rendered button on
   some engines, so it is included rather than assumed harmless. */
input[type="file"] {
  font-size: 16px;
}

/* --- 44px tap targets on checkboxes, radios and their labels ------------ */
input[type="checkbox"],
input[type="radio"] {
  width: 22px;
  height: 22px;
  /* The box itself is 22px; the remaining 22px of target comes from the label
     row's min-height below, which is the surface a thumb actually lands on. */
  flex: 0 0 auto;
  margin: 0;
}

label.check,
.minor-permission label,
.upload-consent label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  /* Without this the row is only as tall as its text and the 44px does
     nothing - the label has to be the target, not just contain one. */
  cursor: pointer;
}

/* The consent text itself stays at its designed size; only the row grows. */
label.check > span,
.minor-permission label > span {
  line-height: 1.4;
}

/* --- Footer links ------------------------------------------------------- */
/* Desktop keeps its density: a mouse does not need 44px, and forcing it there
   would double the height of the footer on every page. Phones get the target,
   which is where the 19px rows were actually being missed. 620px is
   --wiq-bp-phone from style.css, not a new breakpoint. */
@media (max-width: 620px) {
  footer a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}
