/* Playing-card face colour, referenced by Calculators, HandReviews, QuickCapture and Games
     as var(--card-face, ...). The design-system token set has no card-face value, so register
     it here in index.html (the only file we own) to stop the raw hex fallback always firing. */
  :root { --card-face: #F5F5F2; }
  html, body { margin: 0; height: 100%; background: var(--bg); }
  #root { height: 100vh; height: 100dvh; }
  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 999px; }
  @keyframes boot-slide { 0% { transform: translateX(-120%); } 100% { transform: translateX(320%); } }
  .boot-bar { animation: boot-slide 1.1s var(--ease-standard) infinite; }
  @media (prefers-reduced-motion: reduce) { .boot-bar { animation: none; width: 100% !important; } }

  /* ── global polish: focus ring, hover, reduced-motion, touch targets ── */
  button { font-family: var(--font-body); }
  button:active:not(:disabled) { filter: brightness(0.93); }
  @media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

  /* native date/time inputs - match dark/amber branding, kill the default blue segment highlight */
  input[type="datetime-local"], input[type="date"], input[type="time"], input[type="month"] {
    color-scheme: dark;
    accent-color: var(--amber);
  }
  input[type="datetime-local"]::-webkit-calendar-picker-indicator,
  input[type="date"]::-webkit-calendar-picker-indicator,
  input[type="time"]::-webkit-calendar-picker-indicator,
  input[type="month"]::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.85;
    /* tint the white (color-scheme:dark) glyph toward amber #F59E0B */
    filter: invert(70%) sepia(58%) saturate(900%) hue-rotate(347deg) brightness(98%) contrast(94%);
    transition: opacity var(--dur-tap) var(--ease-standard);
  }
  input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover,
  input[type="date"]::-webkit-calendar-picker-indicator:hover,
  input[type="time"]::-webkit-calendar-picker-indicator:hover,
  input[type="month"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
  /* tablet+ shows the app top-bar (with its own bell), so hide the dashboard greeting's duplicate bell - keep it only on phones */
  @media (min-width: 641px) { .dash-greet-bell { display: none !important; } }
  /* Pill-shape safety net: any control wrapper that directly holds a text input/select renders as a pill,
     even if the compiled design-system component still emits an older radius. Sliders/checkboxes excluded. */
  .shell-main [style*="var(--radius-md)"]:has(> input:not([type="range"]):not([type="checkbox"])),
  .shell-main [style*="var(--radius-sm)"]:has(> input:not([type="range"]):not([type="checkbox"])) { border-radius: var(--radius-pill) !important; }
  /* the "odd inner highlight": the focused date/time segment defaults to a blue UA fill - make it an amber tint.
     Each pseudo-element is its OWN rule - grouping vendor pseudo-elements lets one unknown selector void the whole rule. */
  input::-webkit-datetime-edit-year-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-month-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-day-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-hour-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-minute-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-second-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-ampm-field:focus { background: rgba(245,158,11,0.28); color: var(--amber-light); outline: none; border-radius: 3px; }
  input::-webkit-datetime-edit-text { color: var(--text-tertiary); padding: 0 1px; }
  /* native select dropdowns - dark popup + amber highlight instead of the default white/blue list */
  select { color-scheme: dark; accent-color: var(--amber); }
  select option { background-color: var(--surface-2); color: var(--text); }
  select option:hover { background-color: var(--amber-glow); color: var(--amber-light); }
  select option:checked { background: var(--amber-glow) linear-gradient(0deg, var(--amber-glow), var(--amber-glow)); color: var(--amber-light); font-weight: 600; }
  button:focus-visible, a:focus-visible, [role="button"]:focus-visible, [role="tab"]:focus-visible {
    outline: none !important;
    box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--amber) !important;
    border-radius: var(--radius-sm);
  }
  /* form fields manage their own focus (amber border + soft glow) - no double ring */
  input:focus, input:focus-visible, select:focus, select:focus-visible, textarea:focus, textarea:focus-visible { outline: none !important; }
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  }
  @media (max-width: 640px) {
    .shell-bottomnav button { min-height: 44px; }
  }
  /* ── profile hero on phones: buttons and tabs stack full width instead of hugging the right edge ── */
  @media (max-width: 640px) {
    .pf-hero-side { align-items: stretch !important; width: 100%; }
    .pf-hero-side > div:first-child { justify-content: stretch !important; }
    .pf-hero-side > div:first-child > button { flex: 1 1 auto; justify-content: center; }
    .pf-hero-side > div:last-child { display: flex !important; }
    .pf-hero-side > div:last-child > button { flex: 1; }
  }
  /* ── session detail actions on phones: two tidy columns, the last odd button spans the row ── */
  @media (max-width: 640px) {
    .sd-actions { display: grid !important; grid-template-columns: 1fr 1fr; }
    .sd-actions > * { width: 100%; justify-content: center !important; margin-left: 0 !important; box-sizing: border-box; }
    .sd-actions > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  }
  /* ── session detail figure cells: two per row in the stacked layout, an odd last cell spans the row ── */
  .sd-cells { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 20px; column-gap: 8px; }
  .sd-cells > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* ── number tiles: the big value scales with its own tile so long figures (+£3,343.25, 1133.5 hrs) never clip or
     wrap at tablet widths; browsers without container units keep the inline viewport clamp. ── */
  .os-numtile { container-type: inline-size; }
  .os-numtile-value { font-size: clamp(18px, 11.5cqw, 34px) !important; }
  .os-numtile-value + span { flex: none; }
  /* ── tile grids: column count comes from the TileGrid component as a CSS variable ── */
  .os-tilegrid { display: grid; grid-template-columns: repeat(var(--os-cols, 2), minmax(0, 1fr)); }
  /* ── balanced tile grids ── */
  /* A two-up tile grid with an odd number of tiles leaves a lonely half-width card. On phones the
     last odd tile spans the full row so every grid reads as complete. Opt in with .os-balance. */
  @media (max-width: 640px) {
    .os-balance > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  }
  /* ── phone toasts ── */
  /* Both toast hosts (the session-logged Toast and window.osToast) sat bottom-right at a fixed
     width, which on a phone overlapped the floating bottom nav and ran off the left edge.
     Park them above the nav, full width with the page gutter. */
  @media (max-width: 640px) {
    .os-toast-wrap, #os-toast-host { left: 12px !important; right: 12px !important; bottom: 92px !important; align-items: stretch !important; }
    .os-toast-wrap > *, #os-toast-host > * { width: 100% !important; max-width: none !important; min-width: 0 !important; box-sizing: border-box; }
  }
  /* ── phone dialogs ── */
  /* The design-system Dialog is a centred window inside a 24px scrim gutter. On phones that
     leaves a cramped card with its own inner scroll region and pop-ups that clip against it.
     Make it a full-height sheet instead: header pinned, body scrolls, footer pinned. */
  @media (max-width: 640px) {
    div:has(> [data-os-dialog]) { padding: 0 !important; align-items: stretch !important; }
    [data-os-dialog] { max-width: 100% !important; height: 100%; max-height: 100%; border-radius: 0 !important; display: flex; flex-direction: column; }
    [data-os-dialog] > div:first-child { padding: 14px 16px !important; flex: none; }
    [data-os-dialog] > div:not(:first-child):not(:last-child) { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 16px !important; -webkit-overflow-scrolling: touch; }
    [data-os-dialog] > div:last-child { padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px)) !important; flex: none; flex-wrap: wrap; }
  }

  /* ── app shell responsive ── */
  /* desktop only: whole app is one rounded window with even margin */
  /* ≥768px (tablet + desktop): the menu and the top bar are one continuous frame in the same tone, with no divider
     lines; the content sits inside that L-shaped frame like a window, with rounded left corners at the top and bottom.
     (Tom, 12 September: "no lines, it's all joined, with a round edge".) */
  @media (min-width: 768px) {
    .app-shell { position: relative; background: var(--surface-1) !important; }
    .shell-sidebar { position: relative; border-right: 0 !important; background: var(--surface-1) !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
    .shell-brand { border-bottom: 0 !important; }
    .shell-content { background: var(--surface-1); }
    .shell-content .shell-header { border-bottom: 0 !important; box-shadow: none !important; background: var(--surface-1) !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; position: relative; }
    .shell-main { background: var(--bg); border-top-left-radius: 20px; border-bottom-left-radius: 20px; margin-bottom: env(safe-area-inset-bottom, 0px); }
    .shell-sidebar { padding-bottom: env(safe-area-inset-bottom, 0px); }
    .shell-brand, .shell-content .shell-header { height: calc(48px + env(safe-area-inset-top, 0px)) !important; padding-top: env(safe-area-inset-top, 0px) !important; }
    .shell-sidebar::after, .shell-content .shell-header::after, .app-shell::after { content: none !important; display: none !important; }
  }
  @media (min-width: 1920px) {
    .shell-main [style*="max-width: 1320px"] { max-width: 1620px !important; }
    .shell-main [style*="minmax(0px, 1fr) 320px"] { grid-template-columns: minmax(0,1fr) 380px !important; }
    .shell-main [style*="minmax(0px, 1fr) 340px"] { grid-template-columns: minmax(0,1fr) 400px !important; }
    .shell-main [style*="minmax(0px, 1fr) 300px"] { grid-template-columns: minmax(0,1fr) 360px !important; }
  }
  @media (min-width: 2400px) {
    .shell-main [style*="max-width: 1320px"] { max-width: 1880px !important; }
    .shell-main [style*="max-width: 1180px"] { max-width: 1480px !important; }
  }
  /* tablet (≤1023): mirror the desktop layout, but stack the side-rail and 2-column
     panels into one column so the main content + its stat cards get full width.
     Small stat-tile grids (3-/4-up) are left alone, so cards stay desktop-sized. */
  @media (max-width: 1023.98px) {
    /* tablet keeps the sidebar collapse toggle (re-enabled on request) */
    /* tablet uses the mobile dashboard hero - keep the head a row so the kebab pins top-right */
    .shell-main .dash-hero-head { flex-direction: row !important; align-items: flex-start !important; gap: 12px !important; }
    .shell-main .dash-hero-controls { align-self: stretch !important; flex-direction: row !important; align-items: center !important; flex-wrap: wrap !important; gap: 8px !important; }
    .shell-main .dash-hero-meta { flex-wrap: wrap !important; gap: 8px 14px !important; }
    /* stack every screen header (title above, actions below, left-aligned) on tablet + mobile -
       the right-aligned action cluster wraps into a mess otherwise */
    .shell-main .screen-header { flex-direction: column !important; align-items: stretch !important; gap: 14px !important; }
    .shell-main .screen-header > * { justify-content: flex-start !important; }
    /* when the menu is expanded on a narrow (tablet) viewport the content column shrinks -
       drop the multi-column tile grids to 2-up so nothing overflows or hangs off */
    .app-shell.is-expanded .shell-main [style*="repeat(4, 1fr)"], .app-shell.is-expanded .shell-main [style*="repeat(4,1fr)"],
    .app-shell.is-expanded .shell-main [style*="repeat(3, 1fr)"], .app-shell.is-expanded .shell-main [style*="repeat(3,1fr)"] { grid-template-columns: repeat(2, 1fr) !important; }
    /* content + fixed-rail layouts → single column */
    .shell-main [style*="minmax(0px, 1fr)"], .shell-main [style*="minmax(0, 1fr)"],
    .shell-main [style*="1fr 360px"], .shell-main [style*="1fr 340px"],
    .shell-main [style*="1fr 320px"], .shell-main [style*="1fr 300px"] { grid-template-columns: 1fr !important; }
    /* 2-column content panels → single column */
    .shell-main [style*="repeat(2, 1fr)"], .shell-main [style*="repeat(2,1fr)"],
    .shell-main [style*="1fr 1fr"], .shell-main .stats-split, .shell-main .tools-2col { grid-template-columns: 1fr !important; }
    .shell-main .sessions-head { display: none !important; }
    .shell-main .staking-grid { grid-template-columns: repeat(2, 1fr) !important; }
    /* tablet: aggregate KPI strip wraps to 2×2 instead of a 4-wide row that clips off-screen */
    .shell-main .kpi-strip { flex-wrap: wrap !important; padding: 4px 0 !important; }
    .shell-main .kpi-strip > * { flex: 1 1 40% !important; box-sizing: border-box !important; min-width: 0 !important; border-left: 0 !important; padding: 16px 20px !important; }
    .shell-main .kpi-strip > *:nth-child(n+3) { border-top: 1px solid var(--border) !important; }
    /* tablet: KPI tiles 4-up when the rail is collapsed, 2×2 when the menu is expanded (less width) */
    .shell-main .stat-tiles { grid-template-columns: repeat(4, 1fr) !important; }
    .app-shell.is-expanded .shell-main .stat-tiles { grid-template-columns: repeat(2, 1fr) !important; }
    /* auto-fill grids whose min track is wider than the viewport → single column */
    .shell-main [style*="minmax(440px"], .shell-main [style*="minmax(400px"] { grid-template-columns: 1fr !important; }
    .shell-main [style*="position: sticky"] { position: static !important; }
  }
  /* phones (≤640): true bottom bar, mobile top, tighter padding */
  @media (max-width: 640px) {
    .shell-sidebar, .shell-header { display: none !important; }
    .shell-bottomnav { display: flex !important; }
    .shell-main { padding-bottom: 100px !important; }
    /* no top bar on phones, so the first row clears the status bar / notch itself */
    .shell-main > div { padding-left: 16px !important; padding-right: 16px !important; padding-top: calc(22px + env(safe-area-inset-top, 0px)) !important; }
    /* compact cards on phones: tighter padding, shorter tiles, smaller section gaps */
    .shell-main [style*="padding: 32px"] { padding: 18px !important; }
    .shell-main [style*="padding: 28px"] { padding: 18px !important; }
    .shell-main [style*="padding: 26px"] { padding: 16px !important; }
    .shell-main [style*="padding: 24px"] { padding: 16px !important; }
    .shell-main [style*="padding: 20px"] { padding: 16px !important; }
    .shell-main [style*="padding: 18px"] { padding: 16px !important; }
    .shell-main [style*="padding: 22px 20px"] { padding: 15px 14px !important; }
    .shell-main [style*="min-height: 116px"] { min-height: 84px !important; }
    .shell-main .dash-hero-num { font-size: 44px !important; }
    /* phones: hero head stays a row so the kebab menu button pins top-right (controls live in the menu) */
    .shell-main .dash-hero-head { flex-direction: row !important; align-items: flex-start !important; gap: 12px !important; }
    /* compact bankroll hero on phones so the chart stays prominent */
    .shell-main .dash-hero-meta { gap: 6px 14px !important; }
    .shell-main .dash-hero-controls { flex-direction: row !important; align-items: center !important; flex-wrap: wrap !important; gap: 8px !important; }
    .shell-main .dash-hero-controls > * { flex: 0 0 auto !important; }
    /* greeting filters: full-width row under the name, wrapping cleanly (no page overflow) */
    .shell-main .dash-greet-controls { width: 100% !important; justify-content: flex-start !important; gap: 8px !important; }
    /* slimmer founder banner on phones (drop the long sub-line) */
    .shell-main .founder-banner { padding: 12px 14px !important; gap: 10px !important; }
    .shell-main .founder-banner > div:nth-child(2) > div:nth-child(2) { display: none !important; }
    /* stack screen headers: title above, action cluster below (no overlap / clipping) */
    .shell-main .screen-header { flex-direction: column !important; align-items: stretch !important; gap: 14px !important; margin-bottom: 8px !important; }
    .shell-main .screen-header > * { justify-content: flex-start !important; }
    /* KPI strips: 2×2 instead of a 4-wide row that clips off-screen */
    .shell-main .kpi-strip { flex-wrap: wrap !important; padding: 4px 0 !important; }
    .shell-main .kpi-strip > * { flex: 1 1 40% !important; box-sizing: border-box !important; min-width: 0 !important; border-left: 0 !important; padding: 14px 16px !important; }
    .shell-main .kpi-strip > *:nth-child(n+3) { border-top: 1px solid var(--border) !important; }
    /* small stat-tile grids (3- and 4-up) go 2-up on phones rather than full-width 1-up */
    .shell-main [style*="repeat(3, 1fr)"], .shell-main [style*="repeat(3,1fr)"],
    .shell-main [style*="repeat(4, 1fr)"], .shell-main [style*="repeat(4,1fr)"] { grid-template-columns: repeat(2, 1fr) !important; }
    /* dashboard stat tiles stay a tidy 2×2 on phones (the generic repeat(2,1fr)→1fr rule above would otherwise leave them sparse 1-up) */
    .shell-main .stat-tiles { grid-template-columns: repeat(2, 1fr) !important; }
    /* "content + fixed sidebar" grids → single column on phones */
    .shell-main [style*="1fr 360px"], .shell-main [style*="1fr 340px"],
    .shell-main [style*="1fr 320px"], .shell-main [style*="1fr 300px"] { grid-template-columns: 1fr !important; }
    /* auto-fill grids whose min track is wider than the screen → single column */
    .shell-main [style*="minmax(440px"], .shell-main [style*="minmax(400px"],
    .shell-main [style*="minmax(360px"], .shell-main [style*="minmax(340px"] { grid-template-columns: 1fr !important; }
    /* dense fixed-column mini-tables shrink to fit instead of overflowing */
    .shell-main [style*="120px 1fr 70px 90px"] { grid-template-columns: 80px minmax(0,1fr) 46px 60px !important; gap: 8px !important; }
    .shell-main [style*="1fr 90px 110px 120px"] { grid-template-columns: minmax(0,1fr) 52px 60px 68px !important; gap: 6px !important; }
    /* Calculators ICM + DealChop results tables: fixed widths sum past the viewport on phones */
    .shell-main [style*="60px 1fr 120px 90px"] { grid-template-columns: 44px minmax(0,1fr) 80px 60px !important; gap: 6px !important; }
    .shell-main [style*="60px 1fr 130px 130px"] { grid-template-columns: 44px minmax(0,1fr) 80px 80px !important; gap: 6px !important; }
    /* wide tab strips: become a block scroll-container so the inner segmented control keeps
       its natural width and scrolls horizontally (no squeezing/overlap), scrollbar hidden */
    .shell-main .hscroll,
    .shell-main [style*="inline-flex"][style*="align-self: flex-start"],
    .shell-main [style*="width: max-content"] { display: block !important; max-width: 100% !important; overflow-x: auto !important; overflow-y: hidden !important; scrollbar-width: none !important; }
    .shell-main .hscroll::-webkit-scrollbar,
    .shell-main [style*="inline-flex"][style*="align-self: flex-start"]::-webkit-scrollbar,
    .shell-main [style*="width: max-content"]::-webkit-scrollbar { height: 0 !important; width: 0 !important; display: none !important; }
    .shell-main .hscroll > *,
    .shell-main [style*="inline-flex"][style*="align-self: flex-start"] > *,
    .shell-main [style*="width: max-content"] > * { flex: 0 0 auto !important; }
    /* let stat-tile grid children shrink so a wide value can't push the row off-screen */
    .shell-main [style*="repeat(2, 1fr)"] > *, .shell-main [style*="repeat(2,1fr)"] > *,
    .shell-main [style*="repeat(3, 1fr)"] > *, .shell-main [style*="repeat(3,1fr)"] > *,
    .shell-main [style*="repeat(4, 1fr)"] > *, .shell-main [style*="repeat(4,1fr)"] > * { min-width: 0 !important; }
    .shell-main .sessions-head { display: none !important; }
    /* ── touch targets (phones): bring sub-44px controls up to a comfortable tap size ── */
    /* segmented controls on phones: compact, sized to content; scroll sideways only if a long set won't fit (never stretched full-width, never wrapped to two rows) */
    .shell-main [role="tablist"] { display: inline-flex !important; width: auto !important; max-width: 100% !important; flex-wrap: nowrap !important; overflow-x: auto !important; overflow-y: hidden !important; scrollbar-width: none !important; min-height: 40px !important; align-items: center !important; }
    .shell-main [role="tablist"] > [role="tab"] { flex: 0 0 auto !important; min-height: 36px !important; }
    .shell-main [role="tablist"]::-webkit-scrollbar { display: none !important; height: 0 !important; }
    /* Log saved-template pills: taller hit area, label button fills the pill, larger remove control */
    .shell-main [style*="padding: 0px 8px 0px 14px"] { height: 44px !important; }
    .shell-main [style*="padding: 0px 8px 0px 14px"] > button { align-self: stretch !important; display: inline-flex !important; align-items: center !important; }
    .shell-main [title="Remove"] { width: 34px !important; height: 34px !important; }
  }
  /* Drive the sidebar width deterministically from the shell variable (set by AppShell:
     76px collapsed / 256px expanded). Forces past any stray width constraint. */
  .app-shell .shell-sidebar { width: var(--shell-sidebar-w, 256px) !important; min-width: var(--shell-sidebar-w, 256px) !important; max-width: var(--shell-sidebar-w, 256px) !important; }

  /* ── Overshove lockup sting (boot screen) - ported from the brand animation ── */
  .os-sting .chip { transform-box: fill-box; }
  .os-sting .chip-bottom { transform-origin: 50% 100%; }
  .os-sting .chip-mid    { transform-origin: 50% 50%; }
  .os-sting .chip-top    { transform-origin: 50% 50%; transform: rotate(-8deg); }
  .os-sting .os-word { opacity: 1; }
  .os-sting.is-playing .chip-bottom { animation: os-shoveBottom 2.1s linear forwards; }
  .os-sting.is-playing .chip-mid    { animation: os-shoveMid    2.1s linear forwards; }
  .os-sting.is-playing .chip-top    { animation: os-shoveTop    2.1s linear forwards; }
  .os-sting.is-playing .os-word     { animation: os-wordReveal 0.6s cubic-bezier(0.16,1,0.3,1) 1.15s both; }
  @keyframes os-shoveBottom {
    0%   { transform: translate(-150px,0px) scale(1,1);    animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    20%  { transform: translate(0px,0px) scale(1,1);       animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    26%  { transform: translate(0px,0px) scale(0.97,1.03); animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    33%  { transform: translate(0px,0px) scale(1,1); }
    100% { transform: translate(0px,0px) scale(1,1); }
  }
  @keyframes os-shoveMid {
    0%   { transform: translate(-150px,0px) scale(1,1); }
    5%   { transform: translate(-150px,0px) scale(1,1);    animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    26%  { transform: translate(0px,0px) scale(1,1);       animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    32%  { transform: translate(0px,0px) scale(0.97,1.03); animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    39%  { transform: translate(0px,0px) scale(1,1); }
    100% { transform: translate(0px,0px) scale(1,1); }
  }
  @keyframes os-shoveTop {
    0%   { transform: translate(-160px,2px) rotate(0deg);  animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    12%  { transform: translate(-160px,2px) rotate(0deg);  animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    40%  { transform: translate(6px,-3px)  rotate(-12deg); animation-timing-function: cubic-bezier(0.16,1,0.3,1); }
    62%  { transform: translate(0px,0px)   rotate(-8deg); }
    100% { transform: translate(0px,0px)   rotate(-8deg); }
  }
  @keyframes os-wordReveal {
    0%   { opacity: 0; clip-path: inset(0 100% 0 0); transform: translateX(-12px); filter: blur(7px); }
    55%  { opacity: 1; }
    100% { opacity: 1; clip-path: inset(0 0 0 0);    transform: translateX(0);    filter: blur(0); }
  }
  /* the lockup sting is a deliberate brand intro - keep it playing even when reduced-motion
     is on (it overrides the global reduced-motion duration collapse via higher specificity) */
  @media (prefers-reduced-motion: reduce) {
    .os-sting.is-playing .chip-bottom { animation-duration: 2.1s !important; }
    .os-sting.is-playing .chip-mid    { animation-duration: 2.1s !important; }
    .os-sting.is-playing .chip-top    { animation-duration: 2.1s !important; }
    .os-sting.is-playing .os-word     { animation-duration: 0.6s !important; }
  }