@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@300;400;500;600;700&display=swap');

  :root {
    --bg-color: #121212;
    --panel-bg: #1a1a1a;
    --block-color: #242424;
    --text-color: #ffffff;
    --accent-color: rgba(46, 204, 113, 0.4);
    --grid-size: 100px;
    --grid-gap: 10px;
    --radius: 12px;
    --border-color: #333;
    --border-subtle: #2a2a2a;
    --bg-mid: #1f1f1f;
    --bg-elevated: #222;
    --bg-input: #1a1a1a;
    --text-secondary: #ccc;
    --text-muted: #888;
    --text-dim: #555;
    --shadow-md: rgba(0,0,0,0.5);
    --shadow-lg: rgba(0,0,0,0.8);

    /* Chart Colors */
    --c-liv: #3b82f6;
    --c-ars: #ef4444;
    --c-mci: #10b981;
    --c-avl: #f59e0b;
    --c-che: #8b5cf6;
    --c-draw: #6b7280;

    /* Semantic result colours */
    --c-win:  #2ecc71;
    --c-loss: #e74c3c;
    --c-draw: #888888;

    /* Transition speeds */
    --transition-fast: 0.15s ease;
    --transition-base: 0.2s ease;
    --transition-slow: 0.35s ease;

    /* Type scale tokens */
    --t-micro:   0.5rem;
    --t-label:   0.6rem;
    --t-data:    0.7rem;
    --t-body:    0.7rem;
    --t-title:   1rem;
    --t-heading: 1.25rem;
    --t-hero:    1.75rem;
  }

  [data-theme="light"] {
    --bg-color: #f0f0f2;
    --panel-bg: #ffffff;
    --block-color: #e8e8ec;
    --text-color: #111111;
    --accent-color: rgba(46, 204, 113, 0.35);
    --border-color: #d0d0d8;
    --border-subtle: #e0e0e8;
    --bg-mid: #f8f8fa;
    --bg-elevated: #eeeeef;
    --bg-input: #f5f5f7;
    --text-secondary: #444;
    --text-muted: #71717a;
    --text-dim: #a1a1aa;
    --shadow-md: rgba(0,0,0,0.12);
    --shadow-lg: rgba(0,0,0,0.18);
  }

  html {
    background-color: var(--bg-color);
    background-image:
      linear-gradient(to right, #1f1f1f 1px, transparent 1px),
      linear-gradient(to bottom, #1f1f1f 1px, transparent 1px);
    background-size: calc(var(--grid-size) + var(--grid-gap)) calc(var(--grid-size) + var(--grid-gap));
    background-position: 63px 61px;
  }


  body {
    margin: 0;
    padding: 0;
    min-width: 100vw;
    min-height: 100vh;
    color: var(--text-color);
    font-family: 'Instrument Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
  }

  /* Cursor — rooted at body so Chrome's compositor picks it up without lag.
     :has() is supported Chrome 105+ / Safari 15.4+. Falls back to per-element grab. */
  .placed-module          { cursor: grab; }
  .placed-module *        { cursor: grab; }
  .placed-module .resize-handle { cursor: nwse-resize; }
  .module-sub-controls    { cursor: default; }
  .module-sub-controls *  { cursor: default; }
  .module-body            { cursor: default; }
  .module-body *          { cursor: default; }
  #top-bar                { cursor: pointer; }
  #top-bar *              { cursor: pointer; }
  #module-search          { cursor: text !important; }

  /* Top Global Bar */
  #mobile-menu-btn { display: none; }
  #mobile-menu-panel { display: none; }

  #top-bar {
    position: fixed;
    top: 0;
    left: 56px;
    right: 0;
    height: 50px;
    background-color: var(--panel-bg);
    border-bottom: 1px solid #2a2a2a;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0 20px;
    box-sizing: border-box;
    cursor: pointer;
  }
  .top-bar-controls {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  /* Signed-in user's email — an ambient label in the empty left of the top bar
     (WS-D). margin-right:auto (a flex item) pushes it left while the controls
     stay right. Muted + one step below body text so it reads as a label, not a
     button. Empty when signed out → 0-width flex item → the bar is unchanged. */
  .top-bar-user {
    margin-right: auto;
    font-size: var(--t-data);
    color: var(--text-muted);
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: default;
  }

  /* Preset Buttons */
  .preset-group {
    display: flex;
    gap: 6px;
    margin-right: 15px;
    border-right: 1px solid #333;
    padding-right: 15px;
  }
  .preset-btn {
    background: #1a1a1a;
    color: #ccc;
    border: 1px solid #333;
    padding: 4px 10px;
    border-radius: 4px;
    font-size: var(--t-body);
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    text-decoration: none;
    font-family: inherit;
  }
  .preset-btn.icon-btn {
    padding: 4px 8px;
  }
  .preset-btn:hover {
    background: #2a2a2a;
    color: #fff;
    border-color: #2ecc71;
  }
  .clear-btn:hover {
    border-color: #e74c3c !important;
    color: #e74c3c !important;
  }
  .undo-btn:hover {
    border-color: #f39c12 !important;
    color: #f39c12 !important;
  }
  /* Grid Background */
  #workspace {
    position: relative;
    width: calc(24 * (var(--grid-size) + var(--grid-gap)));
    height: calc(48 * (var(--grid-size) + var(--grid-gap)));
    background: transparent;
    margin: 66px 16px 100px 68px; /* left = 56px rail + 12px gap (WS_LEFT in main.js) */
    outline: none;
    transform-origin: 0 0;
    transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
    cursor: grab;
  }


  /* Elegant Welcome Screen */
  #welcome-screen {
    position: absolute;
    transform: translate(-50%, -50%);
    text-align: center;
    z-index: 2;
    transition: opacity 0.5s ease;
    pointer-events: none;
    width: 500px;
  }

  .welcome-buttons {
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-top: 24px;
    pointer-events: auto;
  }

  .welcome-buttons button {
    padding: 10px 28px;
    border-radius: 8px;
    border: none;
    font-size: var(--t-body);
    font-weight: 600;
    cursor: pointer;
    letter-spacing: 0.01em;
    transition: opacity 0.15s;
  }

  .welcome-buttons button:hover { opacity: 0.85; }

  #welcome-tour-btn {
    background: #2ecc71;
    color: #111;
  }

  #welcome-dismiss-btn {
    background: rgba(255,255,255,0.12);
    color: #ccc;
    border: 1px solid rgba(255,255,255,0.15) !important;
  }

  #welcome-screen h1 {
    margin: 0 0 10px 0;
    color: #fff;
    font-size: var(--t-hero);
    font-weight: 600;
    letter-spacing: -0.5px;
    text-shadow: 0 4px 20px rgba(0,0,0,0.8);
  }

  #welcome-screen p {
    margin: 0;
    color: #aaa;
    font-size: var(--t-title);
    text-shadow: 0 2px 10px rgba(0,0,0,0.8);
  }

  #welcome-screen .welcome-byline {
    font-family: 'Barlow Condensed', sans-serif;
    font-size: var(--t-title);
    color: #aaa;
    letter-spacing: 0.12em;
    text-shadow: 0 2px 10px rgba(0,0,0,0.8);
    margin-top: 24px;
  }
  .welcome-byline .byline-prefix { font-weight: 300; }
  .welcome-byline .byline-brand  { font-weight: 600; }
  .var-a { display: inline-block; position: relative; z-index: 1; }
  .byline-static { display: inline-block; position: relative; z-index: 2; }

@keyframes variance-a-fade {
  0%   { opacity: 1; }
  50%  { opacity: 0.25; }
  100% { opacity: 1; }
}

  /* Autonomous Flexing Ghost Blocks */
  .autonomous-ghost {
    position: absolute;
    border: 2px solid #2ecc71;
    border-radius: var(--radius);
    background: rgba(46, 204, 113, 0.08);
    transition: all 0.7s cubic-bezier(0.25, 1, 0.5, 1);
    pointer-events: none;
    z-index: 1;
  }

  /* Permanent Menu Rail */
  #hover-zone {
    position: fixed;
    top: 0;
    left: 0;
    width: 56px;
    height: 100%;
    background-color: var(--panel-bg);
    border-right: 1px solid #2a2a2a;
    z-index: 40;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-top: 20px;
    box-sizing: border-box;
    cursor: pointer;
  }

  /* Slide-out Menu */
  #side-panel {
    position: fixed;
    top: 0;
    left: -40%;
    width: 40%;
    height: 100%;
    background-color: var(--panel-bg);
    box-shadow: 5px 0 15px rgba(0,0,0,0.5);
    transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 30;
    padding: 20px 16px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 8px; 
    overflow-y: auto;
  }

  #side-panel.open {
    left: 0;
  }

  .menu-title {
    font-size: var(--t-title);
    font-weight: 600;
    margin-top: 12px;
    margin-left: 60px;
    margin-bottom: 4px;
    color: #888;
    flex-shrink: 0;
  }

  .menu-title:first-child {
    margin-top: 0;
  }

  /* Menu Layout Updates */
  .menu-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
    margin-left: 60px;
    cursor: grab;
  }

  .module-template {
    background-color: var(--block-color);
    border-radius: var(--radius);
    padding: 5px 3px;
    cursor: grab;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border: 1px solid #333;
    user-select: none;
    transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease, color 0.18s ease;
    color: #ccc;
    font-size: var(--t-data);
    text-align: center;
    aspect-ratio: 3/2;
    box-sizing: border-box;
    touch-action: none;
  }

  .module-template:hover {
    transform: scale(1.04);
    border-color: rgba(46, 204, 113, 0.65);
    box-shadow: 0 0 6px rgba(46, 204, 113, 0.12), 0 0 14px rgba(255, 255, 255, 0.07);
    background-color: rgba(46, 204, 113, 0.07);
    color: #fff;
  }

  .module-template:hover .menu-icon {
    stroke: rgba(46, 204, 113, 0.85);
  }

  .module-template.betting-tile:hover {
    border-color: rgba(100, 160, 220, 0.65);
    box-shadow: 0 0 6px rgba(100, 160, 220, 0.12), 0 0 14px rgba(255, 255, 255, 0.07);
    background-color: rgba(100, 160, 220, 0.07);
  }
  .module-template.betting-tile:hover .menu-icon {
    stroke: rgba(100, 160, 220, 0.85);
  }

  .module-template:active {
    cursor: grabbing;
  }

  .module-template.is-lifting {
    transform: scale(0.96);
    transition: transform 0.08s ease;
  }

  .menu-icon {
    margin-right: 0;
    margin-bottom: 3px;
    width: 18px;
    height: 18px;
    stroke: #888;
    flex-shrink: 0;
    display: inline-block;
    transition: stroke 0.18s ease;
  }

  /* Module search */
  #module-search-wrap {
    position: relative;
    flex-shrink: 0;
    margin-left: 60px;
  }
  #module-search {
    width: 100%;
    box-sizing: border-box;
    background: #1e1e1e;
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    color: #ccc;
    font-size: var(--t-body);
    padding: 8px 28px 8px 10px;
    outline: none;
    transition: border-color 0.15s;
  }
  #module-search:focus { border-color: #555; }
  #module-search::placeholder { color: #4a4a4a; }
  #module-search-clear {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: #555;
    font-size: var(--t-title);
    cursor: pointer;
    padding: 0;
    line-height: 1;
    display: none;
  }
  #module-search-clear.visible { display: block; }
  #search-results {
    display: none;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
    margin-left: 60px;
  }
  #search-results.active { display: grid; }
  .search-empty {
    grid-column: 1 / -1;
    color: #4a4a4a;
    font-size: var(--t-body);
    text-align: center;
    padding: 12px 0;
  }

  /* Ghost block during drag */
  .dragging-ghost {
    position: fixed;
    background-color: var(--block-color);
    border-radius: var(--radius);
    box-shadow: 0 10px 30px rgba(0,0,0,0.8);
    pointer-events: none;
    z-index: 100;
    opacity: 0.4;
    transform-origin: center center;
    transition: transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.1s ease;
  }

  /* Green valid drop glow */
  .snap-indicator {
    position: absolute;
    background-color: var(--accent-color);
    border: 2px solid #2ecc71;
    border-radius: var(--radius);
    pointer-events: none;
    z-index: 5;
    display: none;
  }

  /* While dragging a module it springs between grid cells (main.js; never
     during a resize, where it tracks the cursor). */
  .snap-indicator.snap-spring {
    transition: left 0.28s cubic-bezier(0.34, 1.2, 0.64, 1), top 0.28s cubic-bezier(0.34, 1.2, 0.64, 1);
  }

  /* About to be pushed: a module a drop here would push aside gives the
     resize judder once (main.js previewPushForMove / predictPushed)… */
  .placed-module[data-nervous] { animation: snap-judder 0.2s ease-out; }
  /* …and leans the way it would be pushed, as if repelled (--repel-x, set in
     main.js). `translate` is separate from the judder's `transform`, so the
     two combine; it springs out and eases back. */
  .placed-module {
    translate: var(--repel-x, 0px) 0;
    transition: translate 0.28s cubic-bezier(0.34, 1.2, 0.64, 1);
  }

  /* Red invalid drop glow */
  .snap-indicator.invalid {
    background-color: rgba(231, 76, 60, 0.4);
    border-color: #e74c3c;
  }

  /* Placed Modules */
  .placed-module {
    position: absolute;
    background: linear-gradient(145deg, #333333 0%, #1a1a1a 100%);
    border-radius: var(--radius);
    box-shadow: 0 4px 10px rgba(0,0,0,0.5);
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    border: 1px solid #353535;
    z-index: 6;
    cursor: grab;
  }

  /* Header for moving */
  .module-header {
    height: 40px;
    padding: 0 15px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: grab;
    border-bottom: 1px solid #222;
    background-color: rgba(255,255,255,0.02);
    border-top-left-radius: var(--radius);
    border-top-right-radius: var(--radius);
    user-select: none;
    overflow: hidden;
    touch-action: none;
  }

  .module-header:active {
    cursor: grabbing;
  }

  .module-title {
    font-size: var(--t-body);
    font-weight: 500;
    color: #ccc;
    pointer-events: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-right: 10px;
  }
  
  .header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .module-sub-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 15px;
    background-color: rgba(0, 0, 0, 0.15);
    border-bottom: 1px solid #222;
  }

  .module-controls {
    font-size: var(--t-body);
    color: #aaa;
    background: #1a1a1a;
    padding: 3px 22px 3px 8px;
    border-radius: 4px;
    pointer-events: auto;
    border: 1px solid #333;
    outline: none;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%23555'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 7px center;
    background-size: 7px 4px;
  }

  .module-sub-controls .module-controls {
    background: #222;
    border-color: #444;
  }

  /* ── Desktop dropdown picker ──────────────────────────────────────────────── */
  /* Keyed by CLASS (not the legacy #desktop-picker id) so the React <BentoSelect>
     popover — which renders `.desktop-picker` — shares the exact styling (Phase 4
     seam). The legacy element keeps its id (main.js reads it) and also carries the
     class. */
  .desktop-picker {
    position: fixed;
    z-index: 500;
    background: #1e1e1e;
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.65);
    overflow-y: auto;
    max-height: 280px;
    display: none;
    min-width: 80px;
  }
  .desktop-picker.open { display: block; }
  .desktop-picker-option {
    padding: 7px 12px;
    font-size: var(--t-data);
    color: #999;
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
  }
  .desktop-picker-option:hover { background: #2a2a2a; color: #ddd; }
  .desktop-picker-option.selected { color: #2ecc71; }
  
  .module-pin {
    font-size: var(--t-title);
    line-height: 1;
    margin-top: 2px;
    color: #666;
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    transition: color var(--transition-fast);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
  }
  .module-pin *, .module-pin *:hover { cursor: pointer; }
  .module-pin:hover { color: #aaa; }
  .module-pin.pinned { color: #2ecc71; }

  @keyframes pin-icon-bounce {
    0%   { transform: scale(1); }
    30%  { transform: scale(1.45); }
    60%  { transform: scale(0.88); }
    80%  { transform: scale(1.1); }
    100% { transform: scale(1); }
  }
  @keyframes pin-ring-expand {
    0%   { transform: scale(0.5); opacity: 1; }
    100% { transform: scale(2.6); opacity: 0; }
  }
  .module-pin.pin-animating {
    animation: pin-icon-bounce 0.36s ease-out forwards;
  }
  .module-pin.pin-animating::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 1.5px solid #2ecc71;
    animation: pin-ring-expand 0.42s ease-out forwards;
    pointer-events: none;
  }

  .module-close {
    font-size: var(--t-title);
    line-height: 1;
    color: #666;
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    transition: color var(--transition-fast);
  }

  .module-close:hover {
    color: #e74c3c;
  }

  @keyframes module-close-out {
    0%   { transform: scale(1);    opacity: 1; }
    100% { transform: scale(0.78); opacity: 0; }
  }

  .placed-module.module-closing {
    animation: module-close-out 0.16s ease-in forwards;
    pointer-events: none;
  }

  @keyframes fixture-sel-exit {
    0%   { transform: perspective(500px) rotateX(0deg);   opacity: 1; }
    100% { transform: perspective(500px) rotateX(-80deg); opacity: 0; }
  }
  @keyframes fixture-sel-enter {
    0%   { transform: perspective(500px) rotateX(80deg);  opacity: 0; }
    100% { transform: perspective(500px) rotateX(0deg);   opacity: 1; }
  }
  #global-fixture-select.fixture-sel-exiting {
    animation: fixture-sel-exit 0.12s ease-in forwards;
    transform-origin: top center;
    pointer-events: none;
  }
  #global-fixture-select.fixture-sel-entering {
    animation: fixture-sel-enter 0.16s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
    transform-origin: top center;
    pointer-events: none;
  }

  @keyframes fixture-exit {
    0%   { opacity: 1; transform: translateY(0); }
    100% { opacity: 0; transform: translateY(-8px); }
  }
  @keyframes fixture-enter {
    0%   { opacity: 0; transform: translateY(10px); }
    100% { opacity: 1; transform: translateY(0); }
  }
  .placed-module.fixture-exit {
    animation: fixture-exit 0.13s ease-in forwards;
    pointer-events: none;
  }
  .placed-module.fixture-enter {
    animation: fixture-enter 0.2s ease-out forwards;
    pointer-events: none;
  }

  @keyframes body-exit {
    0%   { opacity: 1; transform: translateY(0); }
    100% { opacity: 0; transform: translateY(-5px); }
  }
  @keyframes body-enter {
    0%   { opacity: 0; transform: translateY(6px); }
    100% { opacity: 1; transform: translateY(0); }
  }
  .module-body.body-exit {
    animation: body-exit 0.12s ease-in forwards;
    pointer-events: none;
  }
  .module-body.body-enter {
    animation: body-enter 0.18s ease-out forwards;
    pointer-events: none;
  }

  /* Module body */
  .module-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #ccc;
    font-size: var(--t-title);
    padding: 15px;
    box-sizing: border-box;
    overflow: hidden;
    overflow-y: auto;
    transition: opacity 0.45s ease;
  }

  .module-body::-webkit-scrollbar { width: 4px; }
  .module-body::-webkit-scrollbar-track { background: transparent; }
  .module-body::-webkit-scrollbar-thumb { background: #444; border-radius: 2px; }
  .module-body::-webkit-scrollbar-thumb:hover { background: #666; }

  /* Zoom UI */
  #zoom-widget {
    position: fixed;
    right: 30px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 200px;
    z-index: 50;
    touch-action: none;
    cursor: grab;
  }
  #zoom-widget::before {
    content: '';
    position: absolute;
    inset: -16px;
    background: rgba(0, 0, 0, 0.75);
    border-radius: 12px;
    z-index: -1;
  }
  .zoom-line {
    position: absolute;
    left: 11px;
    top: 10px;
    bottom: 10px;
    width: 2px;
    background: #333;
  }
  .zoom-dot {
    position: absolute;
    left: 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #555;
    cursor: pointer;
    transition: background 0.2s;
  }
  .zoom-dot[data-idx="0"] { top: 6px; }
  .zoom-dot[data-idx="1"] { top: 51px; }
  .zoom-dot[data-idx="2"] { top: 96px; }
  .zoom-dot[data-idx="3"] { top: 141px; }
  .zoom-dot[data-idx="4"] { top: 186px; }
  
  .zoom-thumb {
    position: absolute;
    left: 4px;
    width: 16px;
    height: 16px;
    background: #2ecc71;
    border-radius: 50%;
    cursor: grab;
    box-shadow: 0 2px 6px rgba(0,0,0,0.5);
    transition: top 0.15s ease-out;
  }
  .zoom-thumb.dragging {
    cursor: grabbing;
    transition: none;
  }

  /* Sports Data Styles */
  .data-wrapper {
    width: 100%;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    container-type: inline-size;
  }
  .data-wrapper.top-align { justify-content: flex-start; }
  
  /* League Table & Lists */
  .data-row { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid #333; font-size: var(--t-body); line-height: 0.8rem; }
  .data-row:last-child { border-bottom: none; }
  .data-row:not(.header):not(.highlighted):nth-child(even) { background: rgba(255,255,255,0.025); }
  .data-row.header { font-weight: 600; color: #888; border-bottom: 2px solid #444; }
  .data-row.highlighted {
    background: rgba(46, 204, 113, 0.15);
  }
  .data-row.highlighted .col-team { font-weight: 600; color: #fff; }
  .col-team { flex: 4; min-width: 60px; text-align: left; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 10px; }
  .col-num { flex: 1; min-width: 22px; text-align: center; }
  .col-num.pts { font-weight: bold; color: #2ecc71; }
  .col-num.xg-pos { font-weight: bold; color: #2ecc71; }
  .col-num.xg-neg { font-weight: bold; color: #e74c3c; }
  .col-opt { display: none; }
  .col-wide { display: none; }
  .col-diff { display: none; }
  .col-delta { display: none; }
  .col-rank { flex: 0 0 28px; text-align: left; }
  .data-row.header .col-rank { cursor: pointer; }
  .data-row.header .sortable { cursor: pointer; }
  .data-row.header .sortable:hover { color: #fff; }
  .data-row.header .sort-asc,
  .data-row.header .sort-desc { color: #fff; }


  @container (min-width: 200px) {
    .col-opt { display: block; }
  }

  @container (min-width: 340px) {
    .col-wide { display: block; }
  }

  @container (min-width: 460px) {
    .col-diff { display: block; }
    .col-delta { display: block; font-size: var(--t-label); flex: 0.75; }
  }
  
  /* Horizontal Bar */
  .bar-wrapper { display: flex; flex-direction: column; gap: 8px; margin-top: 5px; width: 100%; }
  .bar-bg { width: 100%; /* background: #1a1a1a;  */ border-radius: 6px; height: 16px; overflow: hidden; position: relative; }
  .bar-fill { height: 100%; background: var(--accent-color); border-right: 2px solid #2ecc71; transform-origin: left center; }
  @keyframes bar-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  @keyframes snap-judder { 0% { transform: translateX(0); } 15% { transform: translateX(-2px); } 35% { transform: translateX(1px); } 55% { transform: translateX(-1px); } 75% { transform: translateX(1px); } 100% { transform: translateX(0); } }
  .snap-judder { animation: snap-judder 0.2s ease-out; }

  .bar-fill.blue { background: #2d56b4; border-right: none; border-radius: 0 6px 6px 0; }
  .bar-fill.green { background: #2ecc71; border-right: none; border-radius: 0 6px 6px 0; }
  .bar-fill.orange { background: #ce7900; border-right: none; border-radius: 0 6px 6px 0; }
  .bar-fill.blue-light { background: #5d82cc; border-right: none; border-radius: 0 6px 6px 0; }
  .bar-fill.orange-light { background: #e09030; border-right: none; border-radius: 0 6px 6px 0; }
  .bar-fill.team { border-right: none; border-radius: 0 6px 6px 0; }
  .bar-label { position: absolute; top: 0; left: 8px; font-size: var(--t-body); line-height: 16px; color: #fff; font-weight: 600; }
  .bar-value { position: absolute; top: 0; right: 8px; font-size: var(--t-body); line-height: 16px; color: #fff; }

  /* Market Overview Specific */
  .market-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #222; }
  .market-row:last-child { border-bottom: none; }
  .market-label { width: 60px; font-size: var(--t-body); color: #fff; }
  .market-bar-container { flex: 1; margin: 0 10px; background: #1a1a1a; height: 12px; border-radius: 6px; overflow: hidden; }
  .market-bar-fill { height: 100%; background: var(--c-liv); border-radius: 6px; }
  .market-val { width: 30px; text-align: right; font-size: var(--t-body); font-weight: 600; color: #ccc; }

  /* Form Guide */
  .form-container { display: flex; gap: 4px; justify-content: flex-start; align-items: stretch; height: 22px; }
  .form-box { flex: 1 1 0; max-width: 22px; min-width: 0; display: flex; align-items: center; justify-content: center; border-radius: 3px; font-weight: bold; font-size: var(--t-body); color: #fff; cursor: default; user-select: none; position: relative; overflow: hidden; transition: transform 0.12s ease; }
  .form-box:hover { transform: scale(1.2); z-index: 2; }
  .chart-dot { transition: transform 0.12s ease; transform-box: fill-box; transform-origin: center; }
  .chart-dot:hover { transform: scale(1.2); }
  .form-box-bg { position: absolute; inset: 0; border-radius: inherit; z-index: 0; }
  .form-letter { position: relative; z-index: 1; }
  .form-box.bar-lit::after { z-index: 2; }
  .form-w { background-color: var(--c-win); }
  .form-d { background-color: #888; }
  .form-l { background-color: var(--c-loss); }
  .form-team { width: 100%; }
  .form-team + .form-team { margin-top: 14px; }
  .form-team-label { font-size: var(--t-data); color: #fff; margin-bottom: 5px; font-weight: 600; }

  /* Module-specific font-size overrides — use these instead of touching shared rules */
  .module-correct-score-probability-matrix .hm-cell { font-size: var(--t-label); }
  .module-shots-on-target-club .data-row,
  .module-player-disciplinary-records .data-row,
  .module-injury-and-suspension-list .data-row,
  .module-doubtful-players .data-row { font-size: var(--t-data); line-height: var(--t-data); }

  .module-top-scorers-league .bar-label,
  .module-top-scorers-club .bar-label,
  .module-assists-league .bar-label,
  .module-assists-club .bar-label { font-size: var(--t-data); font-weight: 400; }

  .module-league-table .data-row,
  .module-form-table .data-row,
  .module-home-and-away-table .data-row,
  .module-xg-table .data-row { font-size: var(--t-data); line-height: 0.7rem; }

  @media (max-width: 768px) {
    .module-league-table .col-team,
    .module-form-table .col-team,
    .module-xg-table .col-team { flex: 0 0 36px; min-width: 0; }
    .module-xg-table .col-diff { display: block; }
    .module-xg-table .col-delta { display: block; font-size: var(--t-label); flex: 0.75; }
  }
  .module-head-to-head .data-row { font-size: var(--t-data); line-height: 0.7rem; }

  /* Head to Head — scoped additions on top of .data-row / .col-team */
  .h2h-score { flex: 2; text-align: center; font-weight: 600; color: #fff; white-space: nowrap; }
  .h2h-date { flex: 0 0 auto; padding-left: 8px; white-space: nowrap; text-align: right; color: #888; font-size: var(--t-data); }
  .h2h-winner { color: var(--c-win); }

  /* Scored and Conceded */
  .sc-block { margin-bottom: 14px; }
  .sc-block:last-child { margin-bottom: 0; margin-top: 2px; }
  .sc-team-label { font-size: var(--t-data); font-weight: 600; color: #fff; margin-bottom: 4px; margin-top: 4px; }
  .sc-venue { font-weight: 400; color: #888; }
  .sc-stat { margin-bottom: 5px; }
  .sc-stat-header { display: flex; justify-content: space-between; font-size: var(--t-data); margin-bottom: 3px; }
  .sc-stat-name { color: #888; }
  .sc-stat-val { color: #fff; font-weight: 600; }
  .sc-track { position: relative; height: 16px; /* background: #1a1a1a;  */ border-radius: 6px; overflow: hidden; }
  .sc-bar { height: 100%; border-radius: 6px; width: 0%; }
  .sc-scored { background: #2ecc71; }
  .sc-conceded { background: #e74c3c; }
  .hg-half-label { font-size: var(--t-label); font-weight: 600; color: #666; text-transform: uppercase; letter-spacing: 0.05em; margin: 7px 0 2px; }
  .hg-bar-labels { display: flex; justify-content: space-between; margin-bottom: 3px; }
  .hg-label-1h { font-size: var(--t-data); font-weight: 600; color: #666; }
  .hg-label-2h { font-size: var(--t-data); font-weight: 600; color: #888; }
  .hg-split-track { position: relative; height: 16px; background: #1a1a1a; border-radius: 6px; overflow: hidden; display: flex; gap: 3px; margin-bottom: 14px; }
  .hg-1h { height: 100%; flex-shrink: 0; border-radius: 4px; width: 0%; }
  .hg-2h { height: 100%; flex-shrink: 0; border-radius: 4px; width: 100%; }
  /* Scored — two greens: muted 1H, canonical bright 2H */
  .sc-stat[data-stat="sc"] .hg-1h       { background: #27ae60; }
  .sc-stat[data-stat="sc"] .hg-2h       { background: #2ecc71; }
  .sc-stat[data-stat="sc"] .hg-label-1h { color: #27ae60; }
  .sc-stat[data-stat="sc"] .hg-label-2h { color: #2ecc71; }
  /* Conceded — two reds: deep 1H, canonical bright 2H */
  .sc-stat[data-stat="co"] .hg-1h       { background: #c0392b; }
  .sc-stat[data-stat="co"] .hg-2h       { background: #e74c3c; }
  .sc-stat[data-stat="co"] .hg-label-1h { color: #c0392b; }
  .sc-stat[data-stat="co"] .hg-label-2h { color: #e74c3c; }

  /* xG Timeline */
  .xgt-wrapper { width: 100%; height: 100%; flex: 1; min-height: 0; }
  .xgt-svg { display: block; }

  /* Match States */
  .ms-wrapper { width: 100%; height: 100%; flex: 1; min-height: 0; }
  .ms-svg { width: 100%; height: 100%; display: block; overflow: visible; }

  /* Head to Head Trends */
  .h2h-gp-label { color: #fff; }
  .h2h-gp-val { flex: 1; min-width: 36px; text-align: right; color: #888; font-weight: 600; white-space: nowrap; }

  /* .bento-fill — universal hook across all chart fills (bars, donuts, heatmap cells, area paths, dots).
     Add rules here to style all chart elements at once, e.g. opacity: 0.8; */
  .bento-fill { opacity: 0.7; }
    /*   .bento-fill { opacity: 0.4; } */
  .bento-selected { filter: contrast(2.5); }

  /* Shared bar lighting — apply to any horizontal bar fill for a top-light sheen. */
  .bar-lit { position: relative; }

  /* Shared lighting utility — apply to any chart element for a subtle top-left highlight
     and bottom ambient shadow. Uses ::after so the element must not need ::after itself.
     border-radius: inherit means it adapts to circles, rounded rects, or any shape. */
  .chart-lit { position: relative; }
  .chart-lit::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background:
      radial-gradient(ellipse at 38% 22%, rgba(255,255,255,0.18) 0%, transparent 55%),
      radial-gradient(ellipse at 50% 88%, rgba(0,0,0,0.22) 0%, transparent 55%);
    pointer-events: none;
    z-index: 1;
  }

  /* First Goal module */
  /* container-type: size (not inline-size) so we can query height — donuts scale with
     vertical space, not horizontal. Making the module wider without making it taller
     will not trigger any breakpoint. This is the correct pattern for chart modules. */
  .data-wrapper.fg-wrapper {
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    container-type: size;
    container-name: fg;
  }
  .fg-team { display: flex; flex-direction: column; align-items: center; }
  .fg-label { font-size: var(--t-data); color: #fff; font-weight: 600; margin-bottom: 8px; text-align: center; }
  /* Disc background and centre hole should be invisible — module gradient shows through */
  .fg-bg, .fg-hole { fill: transparent; }

  /* BTTS / Clean Sheet block view toggle button */
  .btts-view-btn, .cs-view-btn { margin-left: auto; background: none; border: none; color: #555; cursor: pointer; padding: 2px 3px; display: flex; align-items: center; line-height: 1; }
  .btts-view-btn:hover, .cs-view-btn:hover { color: #aaa; }
  .btts-view-btn .btts-icon-donut, .cs-view-btn .btts-icon-donut { display: none; align-items: center; }
  .btts-view-btn.active .btts-icon-grid, .cs-view-btn.active .btts-icon-grid { display: none; }
  .btts-view-btn.active .btts-icon-donut, .cs-view-btn.active .btts-icon-donut { display: flex; }
  .data-wrapper.btts-block-view, .data-wrapper.cs-block-view { flex-direction: column; justify-content: flex-start; align-items: stretch; gap: 10px; }
  .btts-block-row, .cs-block-row { display: flex; flex-direction: column; gap: 4px; }
  .btts-block-row .fg-label, .cs-block-row .fg-label { margin-bottom: 0; text-align: left; }
  .btts-block-view .form-box, .cs-block-view .form-box { max-height: 22px; }
  .fg-donut-svg { width: 70px; height: 70px; overflow: visible; display: block; }
  .fg-stats { display: flex; gap: 5px; margin-top: 7px; align-items: center; flex-shrink: 0; }
  .fg-w { color: #2ecc71; font-size: var(--t-data); }
  .fg-d { color: #888;    font-size: var(--t-data); }
  .fg-l { color: #e74c3c; font-size: var(--t-data); }

  /* Donut scaling — fluid percentage of the container.
     42cqw keeps two donuts side by side with comfortable spacing.
     75cqh leaves room for the team label above and stats below.
     The smaller of the two always wins, preventing overflow in either direction. */
  .fg-donut-svg { width: min(42cqw, 75cqh); height: min(42cqw, 75cqh); }

  /* Referee History — donut size is set in JS (sizeSvg) to match fg-donut-svg tiers */
  .rwt-donut-svg { overflow: visible; display: block; }

  /* Tooltip */
  #tooltip {
    position: fixed;
    z-index: 9999;
    background: #1a1a1a;
    color: #ddd;
    font-size: var(--t-data);
    line-height: 1.6;
    padding: 6px 10px;
    border-radius: 4px;
    border: 1px solid #444;
    white-space: pre-line;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.12s;
    text-align: left;
  }
  #tooltip.visible { opacity: 1; }

  /* Fixture & Odds */
  .fixture-text { font-size: var(--t-title); font-weight: 800; color: #fff; text-align: center; letter-spacing: 1px; }
  .fixture-sub { font-size: var(--t-body); color: #888; text-align: center; margin-top: 4px; }
  
  /* Betting Button Grid */
  .odds-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; margin-top: 10px; }
  .odds-btn { background: #1a1a1a; padding: 10px; border-radius: 6px; border: 1px solid #333; text-align: center; cursor: pointer; transition: border-color 0.2s; }
  .odds-btn:hover { border-color: #2ecc71; }
  .odds-brand { font-size: var(--t-data); color: #888; margin-bottom: 4px; font-weight: 600; }
  .odds-val { font-size: var(--t-title); font-weight: bold; color: #2ecc71; }
  
  /* Value Indicator Gauge */
  .value-gauge {
    width: 80px; height: 80px; border-radius: 50%;
    background: conic-gradient(#2ecc71 0% 40%, #1a1a1a 40% 100%);
    display: flex; align-items: center; justify-content: center;
    position: relative;
    margin: 0 auto;
  }
  .value-gauge::after {
    content: ''; position: absolute; width: 64px; height: 64px;
    background: var(--block-color); border-radius: 50%;
  }
  .value-text {
    position: relative; z-index: 2; font-weight: bold; font-size: var(--t-title); color: #2ecc71;
  }

  /* Heatmap (Score Prediction) */
  .heatmap-grid { display: grid; grid-template-columns: 20px repeat(5, 1fr); grid-template-rows: repeat(5, 1fr) 20px; gap: 2px; flex: 1; min-height: 0; }
  .hm-cell { border-radius: 6px; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,0.9); font-size: var(--t-label); position: relative; overflow: hidden; }
  .hm-cell-bg { position: absolute; inset: 0; background: inherit; border-radius: inherit; }
  .hm-cell-label { position: relative; z-index: 1; }
  .hm-label { display: flex; align-items: center; justify-content: center; font-size: var(--t-label); color: #888; font-weight: 600; }
  /* Correct Score layout — axes and labels */
  .data-wrapper.csprob-wrapper { flex: 1; min-height: 0; justify-content: flex-start; }
  .csprob-grid-area { display: flex; flex: 1; min-height: 0; align-items: stretch; }
  .csprob-yaxis-label { writing-mode: vertical-lr; transform: rotate(180deg); font-size: var(--t-data); font-weight: 400; color: rgba(255,255,255,0.4); width: 12px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
  .csprob-inner { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0; }
  .csprob-xaxis-label { font-size: var(--t-data); font-weight: 400; color: rgba(255,255,255,0.4); text-align: center; height: 13px; line-height: 13px; flex-shrink: 0; }

  /* Charts */
  .line-svg { width: 100%; height: 100%; margin-top: 10px; flex: 1; }
  .traj-wrapper { justify-content: flex-start; padding: 0 4px 4px 0; box-sizing: border-box; }
  /* traj-chart is a flex row: HTML y-axis labels + SVG side by side.
     Labels are HTML so they never scale with the module — fixed font-size always. */
  .traj-chart { display: flex; flex: 1; width: 100%; min-height: 0; }
  .traj-yaxis { width: 16px; flex-shrink: 0; position: relative; }
  .traj-yaxis span { position: absolute; right: 2px; font-size: var(--t-label); color: #999; transform: translateY(-50%); line-height: 1; white-space: nowrap; }
  .traj-svg { flex: 1; display: block; width: 100%; height: 100%; overflow: visible; min-width: 0; min-height: 0; }
  .traj-xaxis-row { display: flex; flex-shrink: 0; height: 14px; }
  .traj-xaxis-spacer { width: 16px; flex-shrink: 0; }
  .traj-xaxis { flex: 1; position: relative; }
  .traj-xaxis span { position: absolute; font-size: var(--t-label); color: #999; transform: translateX(-50%); line-height: 1; white-space: nowrap; }
  .legend-line-svg { display: inline-block; width: 18px; height: 8px; vertical-align: middle; margin-right: 4px; }
  .ring-chart { width: 80px; height: 80px; border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; }
  .ring-inner { width: 64px; height: 64px; background: var(--block-color); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: var(--t-title); font-weight: bold; color: #fff; }
  .ou-container { display: flex; flex-direction: column; gap: 4px; width: 100%; margin-top: 10px; }
  .ou-block { margin-bottom: 14px; }
  .ou-block:last-child { margin-bottom: 0; }
  .ou-row { margin-bottom: 5px; }
  .ou-bar-bg { position: relative; width: 100%; height: 16px; border-radius: 6px; overflow: hidden; display: flex; background: #1a1a1a; }
  .ou-over-fill { height: 100%; background: #2ecc71; flex-shrink: 0; border-radius: 4px; width: 0%; }
  .ou-under-fill { height: 100%; background: #e74c3c; flex-shrink: 1; min-width: 0; border-radius: 4px; width: 100%; } /* shrinks to make room for the gap (margin-left, set in OverUnder.tsx) */

  /* Goals by Time Band */
  .gtb-svg { flex: 1; min-height: 0; overflow: visible; display: block; width: 100%; }

  /* Legends */
  .legend { display: flex; gap: 12px; justify-content: center; margin-top: 8px; font-size: var(--t-micro); color: #aaa; }
  .traj-legend { justify-content: flex-start; margin-top: 0; margin-bottom: 4px; }
  .traj-legend .legend-item { font-size: var(--t-label); }
  .legend-item { display: flex; align-items: center; gap: 4px; }
  .legend-color { width: 10px; height: 10px; border-radius: 2px; }

  /* Resize handles — 8 directions (the bottom-right one keeps the original
     `.resize-handle` class). Hidden and click-through at rest; shown only on the
     module the store marks as `resizeActiveId` (`.resize-active`, set by the
     sticky-dominance hit-testing in main.js — not CSS :hover, which picks an
     arbitrary winner where two modules' handle zones overlap). */
  .resize-handle,
  .resize-handle-n, .resize-handle-s, .resize-handle-e, .resize-handle-w,
  .resize-handle-ne, .resize-handle-nw, .resize-handle-sw {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    touch-action: none;
    z-index: 3;
  }
  .placed-module.resize-active .resize-handle,
  .placed-module.resize-active .resize-handle-n,
  .placed-module.resize-active .resize-handle-s,
  .placed-module.resize-active .resize-handle-e,
  .placed-module.resize-active .resize-handle-w,
  .placed-module.resize-active .resize-handle-ne,
  .placed-module.resize-active .resize-handle-nw,
  .placed-module.resize-active .resize-handle-sw {
    opacity: 1;
    pointer-events: auto;
  }
  /* No resize arrows on anything while a module (or group) is being dragged. */
  body.is-moving-module .placed-module .resize-handle,
  body.is-moving-module .placed-module .resize-handle-n,
  body.is-moving-module .placed-module .resize-handle-s,
  body.is-moving-module .placed-module .resize-handle-e,
  body.is-moving-module .placed-module .resize-handle-w,
  body.is-moving-module .placed-module .resize-handle-ne,
  body.is-moving-module .placed-module .resize-handle-nw,
  body.is-moving-module .placed-module .resize-handle-sw {
    opacity: 0;
    pointer-events: none;
  }

  /* Marquee multi-select (desktop) */
  .placed-module.module-selected {
    outline: 2px solid #2ecc71;
    outline-offset: -1px;
  }
  #selection-marquee {
    position: fixed;
    /* Above placed modules (z-index 6) but below floating chrome like the
       desktop picker / mobile menu, so a drag never covers an open dropdown. */
    z-index: 50;
    background: rgba(46, 204, 113, 0.12);
    border: 1px solid #2ecc71;
    pointer-events: none;
  }

  /* Thin hover outline — a box-shadow ring, so it can layer with the
     selection outline (a module can be both hovered and selected). */
  .placed-module.resize-active {
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.15), 0 4px 10px rgba(0,0,0,0.5);
  }

  /* Hit-boxes are bigger than the visible arrow; the arrow is centred in its
     box, so it sits just outside the module's edge/corner. */
  .resize-handle    { bottom: -28px; right: -28px; width: 44px; height: 44px; cursor: nwse-resize; }
  .resize-handle-nw { top: -28px; left: -28px; width: 44px; height: 44px; cursor: nwse-resize; }
  .resize-handle-ne { top: -28px; right: -28px; width: 44px; height: 44px; cursor: nesw-resize; }
  .resize-handle-sw { bottom: -28px; left: -28px; width: 44px; height: 44px; cursor: nesw-resize; }
  .resize-handle-n  { top: -25px; left: 50%; transform: translateX(-50%); width: 50px; height: 36px; cursor: ns-resize; }
  .resize-handle-s  { bottom: -25px; left: 50%; transform: translateX(-50%); width: 50px; height: 36px; cursor: ns-resize; }
  .resize-handle-e  { top: 50%; right: -25px; transform: translateY(-50%); width: 36px; height: 50px; cursor: ew-resize; }
  .resize-handle-w  { top: 50%; left: -25px; transform: translateY(-50%); width: 36px; height: 50px; cursor: ew-resize; }

  /* One ">" glyph shared by all 8 handles, rotated to point outward. Base glyph
     points east (0deg); angles increase clockwise. */
  .resize-handle    svg { transform: rotate(45deg); }
  .resize-handle-nw svg { transform: rotate(225deg); }
  .resize-handle-ne svg { transform: rotate(315deg); }
  .resize-handle-sw svg { transform: rotate(135deg); }
  .resize-handle-n  svg { transform: rotate(270deg); }
  .resize-handle-s  svg { transform: rotate(90deg); }
  .resize-handle-e  svg { transform: rotate(0deg); }
  .resize-handle-w  svg { transform: rotate(180deg); }

  body.is-resizing-nwse, body.is-resizing-nwse * { cursor: nwse-resize !important; }
  body.is-resizing-nesw, body.is-resizing-nesw * { cursor: nesw-resize !important; }
  body.is-resizing-ns,   body.is-resizing-ns   * { cursor: ns-resize   !important; }
  body.is-resizing-ew,   body.is-resizing-ew   * { cursor: ew-resize   !important; }
  body.is-dragging-module, body.is-dragging-module *,
  body.is-moving-module, body.is-moving-module * {
    cursor: grabbing !important;
    z-index: 10;
    touch-action: none;
  }

  /* Mobile drag handle — hidden on desktop */
  .mobile-drag-handle { display: none; }
  /* Mobile resize grip — hidden on desktop (shown in the phone block). */
  .mobile-resize-handle { display: none; }

  
  /* Hide mobile-only elements on desktop */
  #mobile-bottom-sheet, #mobile-sheet-backdrop, #mobile-picker, #mobile-picker-backdrop,
  #mobile-welcome-overlay { display: none; }

  /* ── Mobile Layout ──────────────────────────────────── */
  @media (max-width: 768px) {
    /* Hide desktop-only elements */
    #hover-zone, #welcome-screen, .autonomous-ghost, .snap-indicator,
    .resize-handle, .resize-handle-n, .resize-handle-s, .resize-handle-e, .resize-handle-w,
    .resize-handle-ne, .resize-handle-nw, .resize-handle-sw,
    #zoom-widget, #side-panel { display: none !important; }
    .preset-group, #theme-toggle, .top-bar-controls > span { display: none !important; }
    /* The email label is desktop-only for now; the cramped mobile bar holds the
       country/league/fixture selects. A mobile home for it (e.g. the menu panel)
       is a later design-head call. */
    #top-bar-user { display: none !important; }

    /* Mobile welcome overlay */
    #mobile-welcome-overlay {
      position: fixed;
      inset: 0;
      z-index: 300;
      background: #111;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 32px 28px;
      text-align: center;
      transition: opacity 0.4s ease;
    }
    #mobile-welcome-overlay.hidden {
      opacity: 0;
      pointer-events: none;
    }
    #mobile-welcome-canvas {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 0;
    }
    .mobile-welcome-content {
      position: relative;
      z-index: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 100%;
    }
    #mobile-welcome-overlay h1 {
      margin: 0 0 14px;
      color: #fff;
      font-size: var(--t-hero);
      font-weight: 600;
      letter-spacing: -0.5px;
    }
    .mobile-welcome-content p {
      margin: 0;
      color: #aaa;
      font-size: var(--t-title);
      line-height: 1.4;
    }
    #mobile-welcome-overlay .welcome-byline {
      font-family: 'Barlow Condensed', sans-serif;
      font-size: var(--t-title);
      color: #aaa;
      letter-spacing: 0.12em;
      margin-top: 28px;
    }
    #mobile-welcome-tour-btn {
      background: #2ecc71;
      color: #111;
    }
    #mobile-welcome-dismiss-btn {
      background: rgba(255,255,255,0.12);
      color: #ccc;
      border: 1px solid rgba(255,255,255,0.15) !important;
    }

    /* Mobile menu button — hidden on desktop */
    #mobile-menu-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      width: 44px;
      height: 50px;
      background: none;
      border: none;
      color: #aaa;
      cursor: pointer;
      padding: 0 10px;
    }
    #mobile-menu-btn:active { color: #fff; }

    /* Top bar: full width, hamburger left + selects filling the rest */
    #top-bar {
      left: 0;
      padding: 0;
      justify-content: flex-start;
      gap: 0;
      z-index: 200;
    }
    .top-bar-controls {
      flex: 1;
      display: flex;
      align-items: center;
      gap: 6px;
      padding: 0 10px 0 4px;
      min-width: 0;
    }
    #global-country-select { width: 56px; flex-shrink: 0; font-size: var(--t-body); padding: 3px 4px; }
    #global-league-select  { width: 42px; flex-shrink: 0; font-size: var(--t-body); padding: 3px 4px; }
    #global-fixture-select { flex: 1; min-width: 0; font-size: var(--t-body); padding: 3px 4px; }

    /* Mobile menu panel — slides down from top bar */
    #mobile-menu-btn { display: flex; }
    #mobile-menu-panel {
      position: fixed;
      top: 50px; left: 0; right: 0;
      background: #161616;
      border-bottom: 1px solid rgba(255,255,255,0.08);
      z-index: 190;
      display: flex;
      flex-direction: column;
      gap: 10px;
      padding: 12px 12px 14px;
      transform: translateY(-100%);
      transition: transform 0.25s ease;
    }
    #mobile-menu-panel.open { transform: translateY(0); }
    .mobile-menu-label {
      font-size: var(--t-label);
      font-weight: 600;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: #555;
      margin-bottom: 5px;
      display: block;
    }
    .mobile-menu-boards {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
    }
    .mobile-menu-actions {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
    }
    #mobile-menu-panel .preset-btn {
      font-size: var(--t-body);
      font-weight: 400;
      letter-spacing: 0;
      padding: 3px 9px;
      border-radius: 4px;
    }
    #mobile-menu-panel .preset-btn.icon-btn {
      padding: 3px 8px;
      gap: 5px;
    }

    /* Darker greyscale palette on mobile */
    body { background: #080808; }
    :root {
      --block-color: #161616;
      --border-color: #242424;
    }

    html { background-image: none; }

    /* Workspace: the phone layout positions every module itself
       (src/mobile/layout.ts → <Workspace>), so the workspace is a plain
       positioning box whose height comes from the layout (--m-ws-h). */
    #workspace {
      width: 100% !important;
      height: var(--m-ws-h, auto) !important;
      min-height: calc(100vh - 50px);
      margin: 0 !important;
      padding: 58px 6px 100px;
      background: transparent;
      display: block;
      position: relative;
      overflow-anchor: none;
      box-sizing: border-box;
      transform: none !important;
    }

    .module-body {
      overflow-x: auto;
    }

    /* Modules: placed by the phone layout (inline left/top/width/height px).
       Position + size changes glide — a drag's reflow, a resize, a drop.
       iOS-style spring: position overshoots a touch and settles; size just
       eases (an overshooting size would make the content wobble). */
    .placed-module {
      position: absolute !important;
      zoom: unset !important;
      margin: 0;
      transition: left 0.38s cubic-bezier(0.34, 1.4, 0.64, 1), top 0.38s cubic-bezier(0.34, 1.4, 0.64, 1),
                  width 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), height 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
    }

    /* Bottom-edge resize grip (snaps between the three heights). */
    .mobile-resize-handle {
      display: block;
      position: absolute;
      left: 50%;
      bottom: 0;
      transform: translateX(-50%);
      width: 56px;
      height: 20px;
      touch-action: none;
      cursor: ns-resize;
      z-index: 4;
    }
    .mobile-resize-handle::after {
      content: '';
      position: absolute;
      left: 50%;
      bottom: 6px;
      transform: translateX(-50%);
      width: 28px;
      height: 4px;
      border-radius: 2px;
      background: rgba(255, 255, 255, 0.28);
    }
    [data-theme="light"] .mobile-resize-handle::after { background: rgba(0, 0, 0, 0.22); }
    /* Head to Head on a phone: short club codes (HeadToHead.tsx) leave room for
       the date, which narrow modules otherwise hide (.col-opt). */
    /* Four fixed columns — home, score, away 20% each (teams left-aligned,
       score centred), date 40% (right-aligned) — so every row lines up at any
       module width. */
    .module-head-to-head .col-team,
    .module-head-to-head .h2h-score { flex: 0 0 20%; min-width: 0; padding: 0; text-align: left; }
    .module-head-to-head .h2h-score { text-align: center; }
    .module-head-to-head .h2h-date { display: block; flex: 0 0 40%; padding: 0; text-align: right; }

    /* Bottom tray — always visible */
    #mobile-tray {
      position: fixed;
      bottom: 0; left: 0; right: 0;
      height: 48px;
      background: #161616;
      border-top: 1px solid #2ecc71;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      z-index: 200;
      user-select: none;
      -webkit-user-select: none;
    }
    #mobile-tray-label {
      font-size: var(--t-data);
      font-weight: 600;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: #2ecc71;
      pointer-events: none;
    }
    #mobile-tray.placement-cancel #mobile-tray-label { color: #e74c3c; }

    /* Workspace clearance for the tray */
    #workspace { padding-bottom: 48px; }

    /* Bottom sheet backdrop */
    #mobile-sheet-backdrop {
      display: block;
      position: fixed; inset: 0;
      background: rgba(0,0,0,0.55);
      z-index: 150;
      opacity: 0; pointer-events: none;
      transition: opacity 0.3s ease;
    }
    #mobile-sheet-backdrop.visible { opacity: 1; pointer-events: auto; }

    /* Bottom sheet — sits above the tray */
    #mobile-bottom-sheet {
      display: flex;
      flex-direction: column;
      position: fixed;
      bottom: 48px; left: 0; right: 0;
      background: #1c1c1c;
      border-radius: 16px 16px 0 0;
      z-index: 160;
      transform: translateY(100%);
      transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
      max-height: 72vh;
    }
    #mobile-bottom-sheet.open { transform: translateY(0); }
    #mobile-bottom-sheet.collapsed { transform: translateY(calc(100% - 56px)); transition: transform 0.2s ease; }

    .mobile-sheet-handle {
      width: 36px; height: 4px;
      background: #444; border-radius: 2px;
      margin: 10px auto 6px; flex-shrink: 0;
    }
    .mobile-sheet-title {
      font-size: var(--t-data); font-weight: 600; color: #888;
      text-align: center; padding-bottom: 10px; flex-shrink: 0;
    }
    .mobile-sheet-search-wrap {
      display: flex;
      align-items: center;
      gap: 6px;
      padding: 8px 10px 6px;
      flex-shrink: 0;
    }
    #mobile-sheet-search {
      flex: 1;
      background: #2a2a2a;
      border: 1px solid #3a3a3a;
      border-radius: 8px;
      color: #eee;
      font-size: 16px;
      padding: 7px 10px;
      outline: none;
    }
    #mobile-sheet-search::placeholder { color: #888; font-size: var(--t-body); }
    #mobile-sheet-search-clear {
      background: none;
      border: none;
      color: #555;
      font-size: var(--t-title);
      cursor: pointer;
      padding: 4px 6px;
      line-height: 1;
      display: none;
    }
    #mobile-sheet-search-clear.visible { display: block; }
    .mobile-sheet-tile.hidden { display: none; }

    .mobile-sheet-tiles {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 8px;
      padding: 0 10px 10px;
      overflow-y: auto;
      flex: 1;
      min-height: 0;
    }
    .mobile-sheet-group-label {
      grid-column: 1 / -1;
      font-size: var(--t-label);
      font-weight: 600;
      color: #666;
      text-transform: uppercase;
      letter-spacing: 0.1em;
      padding: 10px 0 2px;
    }
    .mobile-sheet-group-label.hidden { display: none; }
    .mobile-sheet-tile {
      background: #2d2d2d;
      border-radius: 10px;
      display: flex; flex-direction: column;
      align-items: center; justify-content: center;
      gap: 5px; padding: 12px 6px;
      font-size: var(--t-label); color: #ccc;
      text-align: center; line-height: 1.3;
      cursor: pointer;
      user-select: none; -webkit-user-select: none;
      touch-action: manipulation;
      transition: opacity 0.15s ease;
    }
    .mobile-sheet-tile:active { opacity: 0.6; }
    .mobile-sheet-tile span {
      display: flex;
      align-items: flex-start;
      justify-content: center;
      min-height: calc(1.3em * 2);
    }
    .mobile-sheet-tile svg { width: 18px; height: 18px; stroke: #888; flex-shrink: 0; }

    /* Header: long-press to lift. "manipulation" keeps scrolling but drops
       double-tap-to-zoom, so iOS doesn't hold back a press that follows a
       recent tap (e.g. the press after a drop) waiting for a second tap. */
    .module-header {
      touch-action: manipulation;
      cursor: default;
      user-select: none;
      -webkit-user-select: none;
    }

    /* Ringfence the action buttons — restore normal touch behaviour and
       give each button a generously sized tap target */
    .module-header .header-actions {
      touch-action: auto;
      cursor: default;
      flex-shrink: 0;
      gap: 0;
    }
    .module-header .module-pin { display: none; }
    .module-header .module-close {
      min-width: 44px;
      min-height: 44px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      font-size: var(--t-hero);
    }
    .module-header .mobile-drag-handle {
      justify-content: flex-start;
    }

    /* Drag handle — visible on mobile */
    .mobile-drag-handle {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      flex-shrink: 0;
      color: #999;
      cursor: grab;
      touch-action: none;
      user-select: none;
      -webkit-user-select: none;
    }


    /* ── Phone drag (src/mobile/engine.ts) ──────────────────────────────── */
    /* Long-press feedback: the module sinks a touch while the hold counts. */
    .placed-module.m-pressing {
      transform: scale(0.985);
      transition: transform 0.3s ease;
    }
    /* Lifted: a stand-in card follows the finger (transform only — no layout
       work per frame) above everything, with a deep shadow. It's the module's
       header + its skeleton outline, so it can morph to the shape of the slot
       it's aiming at (width / height transition; engine.ts applyOption) for
       next to nothing. Same look as .placed-module, but its own class — legacy
       code finds modules by .placed-module. */
    .m-proxy {
      position: absolute;
      z-index: 300;
      display: flex;
      flex-direction: column;
      box-sizing: border-box;
      overflow: hidden;
      background: linear-gradient(145deg, #333333 0%, #1a1a1a 100%);
      border: 1px solid #353535;
      border-radius: var(--radius);
      box-shadow: 0 22px 60px rgba(0, 0, 0, 0.75);
      transition: width 0.24s cubic-bezier(0.2, 0.8, 0.2, 1), height 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
      will-change: transform;
      cursor: grabbing;
    }
    .m-proxy .module-body { flex: 1; min-height: 0; overflow: hidden; }
    [data-theme="light"] .m-proxy {
      background: linear-gradient(150deg, #f4f4f8 0%, #dcdce0 100%);
      border-color: var(--border-color);
      box-shadow: 0 22px 60px rgba(0, 0, 0, 0.25);
    }
    /* Dropping: glide from the finger into the slot. */
    .m-proxy.m-dropping {
      transition: transform 0.38s cubic-bezier(0.34, 1.4, 0.64, 1), left 0.38s cubic-bezier(0.34, 1.4, 0.64, 1),
                  top 0.38s cubic-bezier(0.34, 1.4, 0.64, 1), width 0.3s cubic-bezier(0.2, 0.8, 0.2, 1),
                  height 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.3s ease;
      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
    }
    /* The real module while its stand-in is lifted: hidden in place, and moved
       to its slot in one step on drop (no transition). Then it fades up. */
    .placed-module.m-origin { visibility: hidden; transition: none !important; }
    .placed-module.m-arrived > * { animation: bm-reveal 0.25s ease-out; }
    /* The landing slot — the desktop snap indicator's green ghost, the exact
       shape the module will take; it glides between slots as you aim. */
    .m-slot {
      position: absolute;
      z-index: 1;
      background: var(--accent-color);
      border: 2px solid #2ecc71;
      border-radius: var(--radius);
      box-sizing: border-box;
      pointer-events: none;
      transition: left 0.3s cubic-bezier(0.34, 1.4, 0.64, 1), top 0.3s cubic-bezier(0.34, 1.4, 0.64, 1),
                  width 0.24s cubic-bezier(0.2, 0.8, 0.2, 1), height 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
    }
    .m-slot.m-slot-instant { transition: none; }
    /* Placing from the tray: the ghost says what to do. */
    .m-slot.m-slot-placing {
      display: flex;
      align-items: flex-end;
      justify-content: center;
      padding: 0 8px 10px;
      color: #2ecc71;
      font-size: var(--t-label);
      font-weight: 600;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      text-align: center;
    }
    /* Headers: a long press shouldn't select text or open iOS's callout. */
    .module-header { -webkit-touch-callout: none; }
    /* (Motion is deliberately NOT reduced for prefers-reduced-motion on phones
       — the spring is the interaction.) */

    @keyframes mobile-module-pop-in {
      0%   { transform: scale(0.65); opacity: 0;   box-shadow: inset 0 0 0    0px rgba(0,0,0,0); }
      22%  { transform: scale(1.04); opacity: 1;   box-shadow: inset 0 0 40px 80px rgba(0,0,0,0.85); }
      55%  { transform: scale(0.97);               box-shadow: inset 0 0 0    0px rgba(0,0,0,0); }
      100% { transform: scale(1);                  box-shadow: inset 0 0 0    0px rgba(0,0,0,0); }
    }
    .placed-module.mobile-pop-in {
      animation: mobile-module-pop-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
      will-change: transform, opacity;
    }

    /* ── Mobile dropdown picker ──────────────────────────────────────────────── */
    #mobile-picker-backdrop {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.55);
      z-index: 309;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.25s ease;
    }
    #mobile-picker-backdrop.active { opacity: 1; pointer-events: auto; }

    #mobile-picker {
      position: fixed;
      bottom: 0; left: 0; right: 0;
      background: #1c1c1c;
      border-radius: 16px 16px 0 0;
      z-index: 310;
      transform: translateY(100%);
      transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
      max-height: 60vh;
      display: flex;
      flex-direction: column;
    }
    #mobile-picker.open { transform: translateY(0); }

    .mobile-picker-handle {
      width: 36px; height: 4px;
      background: #444; border-radius: 2px;
      margin: 10px auto 6px; flex-shrink: 0;
    }
    .mobile-picker-title {
      font-size: var(--t-data);
      font-weight: 600;
      color: #888;
      text-align: center;
      padding-bottom: 6px;
      flex-shrink: 0;
    }
    .mobile-picker-list {
      overflow-y: auto;
      flex: 1;
      -webkit-overflow-scrolling: touch;
      padding-bottom: env(safe-area-inset-bottom, 16px);
    }
    .mobile-picker-option {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 15px 20px;
      font-size: var(--t-body);
      color: #ccc;
      border-bottom: 1px solid #2a2a2a;
      -webkit-tap-highlight-color: transparent;
    }
    .mobile-picker-option:last-child { border-bottom: none; }
    .mobile-picker-option:active { background: #252525; }
    .mobile-picker-option.selected { color: #2ecc71; }
    .mobile-picker-option.selected::after { content: '✓'; color: #2ecc71; }

    /* Inline picker — expands between sub-controls and visualization */
    .mobile-inline-picker {
      /* Overlays the module body below the controls (top set in JS). */
      position: absolute;
      left: 0;
      right: 0;
      z-index: 20;
      overflow-x: hidden;
      overflow-y: auto;
      max-height: 0;
      transition: max-height 0.28s ease;
      background: #181818;
      border-bottom: 1px solid #2a2a2a;
      flex-shrink: 0;
    }
    .mobile-inline-picker-option {
      padding: 14px 15px;
      font-size: var(--t-body);
      color: #bbb;
      border-bottom: 1px solid #222;
      -webkit-tap-highlight-color: transparent;
    }
    .mobile-inline-picker-option:last-child { border-bottom: none; }
    .mobile-inline-picker-option:active { background: #222; }
    .mobile-inline-picker-option.selected { color: #2ecc71; }
    .mobile-inline-picker-option.selected::after { content: ' ✓'; }

  }

/* Modular architecture helpers */
.module-loading,
.module-error {
  width: 100%;
  min-height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #777;
  font-size: var(--t-body);
}
.module-error {
  color: #e74c3c;
  line-height: 1.4;
}
/* "Coming soon" placeholder — widgets whose real data isn't wired yet (the
   player/discipline club family). Mid greys read fine on both themes, matching
   .module-loading/.module-error which also skip a light-theme override. */
.module-coming-soon {
  width: 100%;
  min-height: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  text-align: center;
}
.module-coming-soon .mcs-title {
  font-size: var(--t-title);
  color: #999;
  letter-spacing: 0.01em;
}
.module-coming-soon .mcs-sub {
  font-size: var(--t-label);
  color: #666;
}

  /* HT/FT module — toggle button */
  .htft-view-btn { margin-left: auto; background: none; border: none; color: #555; cursor: pointer; padding: 2px 3px; display: flex; align-items: center; line-height: 1; }
  .htft-view-btn:hover { color: #aaa; }
  .htft-icon-bars { display: flex; align-items: center; }
  .htft-icon-flow { display: none; align-items: center; }
  .htft-view-btn.active .htft-icon-bars { display: none; }
  .htft-view-btn.active .htft-icon-flow { display: flex; }

  /* 1st/2nd Half Goals — dot-timeline view */
  .hg-view-btn { margin-left: auto; background: none; border: none; color: #555; cursor: pointer; padding: 2px 3px; display: flex; align-items: center; line-height: 1; }
  .hg-view-btn:hover { color: #aaa; }
  .hg-icon-bars { display: flex; align-items: center; }
  .hg-icon-dots { display: none; align-items: center; }
  .hg-view-btn.active .hg-icon-bars { display: none; }
  .hg-view-btn.active .hg-icon-dots { display: flex; }
  .hg-bands-wrapper { flex-direction: column; overflow: visible; }
  .hg-bands-canvas { display: block; flex-shrink: 0; }

  /* HT/FT flow (alluvial) view */
  .data-wrapper.htft-wrapper { flex-direction: column; }
  .htft-stat-w { color: #2ecc71; }
  .htft-stat-d { color: #888; }
  .htft-stat-l { color: #e74c3c; }
  .htft-svg { flex: 1; min-height: 0; overflow: visible; display: block; width: 100%; }

  /* HT/FT bar chart view */
  .htft-bars-block { width: 100%; }
  .htft-bars-block .sc-stat-name { color: #fff; }
  .htft-bars-block .ou-row { margin-bottom: 18px; }
  .htft-bars-block .ou-bar-bg { gap: 3px; } /* HT/FT's W/D/L bars keep the fixed gap (Over/Under now sets its own) */
  .htft-bars-block .ou-row:last-child { margin-bottom: 0; }
  .htft-bf-w { height: 100%; background: #2ecc71; flex-shrink: 0; width: 0%; border-radius: 3px; }
  .htft-bf-d { height: 100%; background: #888; flex-shrink: 0; width: 0%; border-radius: 3px; }
  .htft-bf-l { height: 100%; background: #e74c3c; flex-shrink: 0; width: 0%; border-radius: 3px; }
  .htft-bstat { display: flex; gap: 6px; font-size: var(--t-data); }


/* ===== LIGHT THEME ===== */
[data-theme="light"] body { color: #111; }

/* Top bar & sidebar */
[data-theme="light"] #top-bar { border-bottom-color: var(--border-color); }
[data-theme="light"] #hover-zone { border-right-color: var(--border-color); }
[data-theme="light"] #side-panel { box-shadow: 5px 0 15px rgba(0,0,0,0.1); }
[data-theme="light"] .menu-title { color: var(--text-muted); }
[data-theme="light"] .menu-icon { stroke: var(--text-muted); }

/* Module templates in sidebar */
[data-theme="light"] .module-template { border-color: var(--border-color); color: var(--text-secondary); }
[data-theme="light"] .module-template:hover { border-color: rgba(46, 204, 113, 0.75); background-color: rgba(46, 204, 113, 0.06); box-shadow: 0 0 10px rgba(46, 204, 113, 0.18), 0 0 22px rgba(46, 204, 113, 0.07); }

/* Preset buttons */
[data-theme="light"] .preset-btn { background: var(--bg-input); color: var(--text-secondary); border-color: var(--border-color); }
[data-theme="light"] .preset-btn:hover { background: var(--bg-elevated); color: #111; }

/* Module search */
[data-theme="light"] #module-search { background: var(--bg-input); border-color: var(--border-color); color: #111; }
[data-theme="light"] #module-search::placeholder { color: var(--text-dim); }
[data-theme="light"] #module-search-clear { color: var(--text-muted); }
[data-theme="light"] .search-empty { color: var(--text-dim); }

/* ── Penalty Takers ─────────────────────────────────── */
  .module-body.pt-body { justify-content: flex-start; }
  .pt-wrapper { display: flex; flex-direction: column; gap: 14px; width: 100%; }
  .pt-wrapper .sc-block { margin-bottom: 0; margin-top: 0; }
  .pt-empty { color: #888; font-size: var(--t-body); }

/* Module cards */
[data-theme="light"] .placed-module { background: linear-gradient(150deg, #f4f4f8 0%, #dcdce0 100%); border-color: var(--border-color); box-shadow: 0 4px 10px var(--shadow-md); }
[data-theme="light"] .module-header { border-bottom-color: var(--border-subtle); background-color: rgba(0,0,0,0.04); }
[data-theme="light"] .module-title { color: var(--text-secondary); }
[data-theme="light"] .module-sub-controls { background-color: rgba(0,0,0,0.04); border-bottom-color: var(--border-subtle); }
[data-theme="light"] .module-controls { background: var(--bg-input); color: #333; border-color: var(--border-color); }
[data-theme="light"] .module-sub-controls .module-controls { background: var(--bg-elevated); border-color: var(--border-color); }
[data-theme="light"] .module-body { color: #333; }
[data-theme="light"] .module-body::-webkit-scrollbar-thumb { background: #bbb; }
[data-theme="light"] .module-close { color: var(--text-dim); }
[data-theme="light"] .module-pin { color: var(--text-dim); }
[data-theme="light"] .module-pin:hover { color: #555; }
[data-theme="light"] .resize-handle,
[data-theme="light"] .resize-handle-n, [data-theme="light"] .resize-handle-s,
[data-theme="light"] .resize-handle-e, [data-theme="light"] .resize-handle-w,
[data-theme="light"] .resize-handle-ne, [data-theme="light"] .resize-handle-nw,
[data-theme="light"] .resize-handle-sw { color: #555; }
[data-theme="light"] .placed-module.resize-active { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12), 0 4px 10px var(--shadow-md); }
[data-theme="light"] .placeholder { border-color: #bbb !important; }
[data-theme="light"] .dragging-ghost { box-shadow: 0 10px 30px rgba(0,0,0,0.2); }

/* Workspace grid lines */
[data-theme="light"] html {
  background-image:
    linear-gradient(to right, #e0e0e4 1px, transparent 1px),
    linear-gradient(to bottom, #e0e0e4 1px, transparent 1px);
}

/* Data tables */
[data-theme="light"] .data-row { border-bottom-color: var(--border-color); }
[data-theme="light"] .data-row:not(.header):not(.highlighted):nth-child(even) { background: rgba(0,0,0,0.03); }
[data-theme="light"] .data-row.header { color: var(--text-muted); border-bottom-color: var(--border-color); }
[data-theme="light"] .data-row.header .sortable:hover { color: #111; }
[data-theme="light"] .data-row.highlighted .col-team { color: #111; }
[data-theme="light"] .col-team { color: #111; }

/* Charts / viz text */
[data-theme="light"] .traj-yaxis span { color: var(--text-muted); }
[data-theme="light"] .traj-xaxis span { color: var(--text-dim); }
[data-theme="light"] .legend { color: var(--text-muted); }
[data-theme="light"] .hg-half-label { color: var(--text-muted); }
[data-theme="light"] .hg-label-1h { color: #555; }
[data-theme="light"] .hg-label-2h { color: var(--text-muted); }
[data-theme="light"] .fg-label { color: #111; }
[data-theme="light"] .fg-stats { color: #333; }
[data-theme="light"] .h2h-date { color: var(--text-muted); }
[data-theme="light"] .h2h-score { color: #111; }
[data-theme="light"] .sc-venue { color: var(--text-muted); }
[data-theme="light"] .sc-stat-name { color: var(--text-muted); }
[data-theme="light"] .sc-stat-val { color: #111; }
[data-theme="light"] .sc-team-label { color: #111; }
[data-theme="light"] .form-team-label { color: #111; }
[data-theme="light"] .h2h-gp-label { color: #111; }
[data-theme="light"] .h2h-gp-val { color: var(--text-muted); }
[data-theme="light"] .htft-bars-block .sc-stat-name { color: #333; }
[data-theme="light"] .htft-stat-d { color: #888; }

/* Bar/track backgrounds in light mode */
[data-theme="light"] .bar-bg { background: var(--bg-elevated); }
[data-theme="light"] .sc-track { background: var(--bg-elevated); }
[data-theme="light"] .hg-split-track { background: var(--bg-elevated); }
[data-theme="light"] .ou-bar-bg { background: var(--bg-elevated); }

/* Heatmap */
[data-theme="light"] .hm-label { color: var(--text-muted); }
[data-theme="light"] .hm-cell { color: rgba(0,0,0,0.8); }
[data-theme="light"] .csprob-yaxis-label,
[data-theme="light"] .csprob-xaxis-label { color: rgba(0,0,0,0.4); }

/* Tooltip */
[data-theme="light"] #tooltip { background: #fff; color: #333; border-color: var(--border-color); }

/* Zoom widget */
[data-theme="light"] .zoom-line { background: var(--border-color); }
[data-theme="light"] .zoom-dot { background: var(--text-dim); }

/* Theme toggle hidden */
#theme-toggle { display: none !important; }
#theme-toggle .theme-icon-sun { display: none; }
[data-theme="light"] #theme-toggle .theme-icon-moon { display: none; }
[data-theme="light"] #theme-toggle .theme-icon-sun { display: block; }

/* Mobile */
@media (max-width: 768px) {
  [data-theme="light"] #side-panel { background-color: #fff; border-bottom-color: var(--border-color); }
  [data-theme="light"] #top-bar { border-bottom-color: var(--border-color); }
}



/* ── Betting module theme ───────────────────────────────────────────────────
   Apply .betting-module to .placed-module to activate. CSS custom properties
   cascade to all descendants so renderers can use var(--bm-X) in inline styles. */
.betting-module {
  --bm-header:  #152030;
  --bm-border:  #121e2c;
  --bm-text:    #a8c0d0;
  --bm-prob:    #4e6878;
  border-color: #0e1a28 !important;
}
.betting-module .module-header {
  background-color: #0e1a28;
  border-bottom-color: #121e2c;
}
.betting-module .module-sub-controls {
  background-color: #0a1420;
  border-bottom-color: #121e2c;
}
.betting-module .module-sub-controls .module-controls {
  background: #0e1a28;
  border-color: #1e3048;
  color: #a8c0d0;
}
.betting-module .module-body {
  background: #0d1520 !important;
  padding: 0;
}
.ref-link-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid #3a3a3a;
  border-radius: 3px;
  background: #1a1a1a;
  color: #888;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s;
}
.ref-link-btn:hover { color: #aaa; border-color: #555; }
.ref-link-btn.unlinked { color: #444; border-color: #2a2a2a; }
.ref-link-btn.unlinked:hover { color: #666; }
.ref-link-btn svg { width: 11px; height: 11px; }
.bk-link-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid #1e3048;
  border-radius: 3px;
  background: #0e1a28;
  color: #4a9eda;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s;
}
.bk-link-btn:hover { color: #7bbfef; border-color: #2a5070; }
.bk-link-btn.unlinked { color: #3a5068; border-color: #1a2a3a; }
.bk-link-btn.unlinked:hover { color: #5a7a8a; }
.bk-link-btn svg { width: 11px; height: 11px; }
.market-row-hl {
  background: rgba(var(--mhl-rgb), 0.14) !important;
  box-shadow: inset 3px 0 0 rgb(var(--mhl-rgb));
  transition: background 0.15s, box-shadow 0.15s;
}
.bm-scroll { overflow-y: auto; flex: 1; scrollbar-width: thin; scrollbar-color: #1e3a52 transparent; }
.bm-scroll::-webkit-scrollbar { width: 4px; }
.bm-scroll::-webkit-scrollbar-track { background: transparent; }
.bm-scroll::-webkit-scrollbar-thumb { background: #1e3a52; border-radius: 2px; }
.bm-scroll::-webkit-scrollbar-thumb:hover { background: #2a5070; }

/* ── Betting module layout classes ────────────────────────────────────────── */
/* Wrapper fills the module body with a vertical flex column */
.bm-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Sticky header row */
.bm-hdr {
  display: flex;
  align-items: center;
  padding: 4px 15px;
  background: var(--bm-header);
  border-bottom: 1px solid var(--bm-border);
  flex-shrink: 0;
}
/* Header cell text */
.bm-hdr-cell {
  font-size: var(--t-label);
  color: #7a9db8;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
/* Data row */
.bm-row {
  display: flex;
  align-items: center;
  padding: 9px 15px;
  border-bottom: 1px solid var(--bm-border);
}
.bm-row--alt { background: rgba(255,255,255,0.03); }
/* Primary odds/text */
.bm-txt {
  font-size: var(--t-data);
  color: var(--bm-text);
  font-weight: 600;
}
/* Implied probability sub-text */
.bm-prob {
  font-size: var(--t-label);
  color: #5a7a8a;
}
/* Row label (O/2.5, player name, etc.) */
.bm-lbl {
  font-size: var(--t-label);
  color: #7a9db8;
  font-weight: 600;
  text-transform: uppercase;
}
/* Alignment helpers */
.bm-center { text-align: center; }
.bm-right  { text-align: right; }
/* Stacked cell: odds on top, prob below (narrow layout) */
.bm-cell-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
}
/* Inline cell: odds then prob on one line (wide layout) */
.bm-cell-inline {
  display: flex;
  align-items: baseline;
  gap: 3px;
}
/* Best-price cell: odds + badge */
.bm-best-cell {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
}
/* Bookmaker badge */
.bm-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  padding: 1px 4px;
  min-width: 22px;
  height: 16px;
}
.bm-badge-text {
  font-size: var(--t-micro);
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.04em;
}

/* ── Goals/Cards/1X2 Market — narrow layout column widths ─────────────────── */
.bmc-lbl-n  { flex: 0 0 46px; }
.bmc-cell-n { flex: 1; }
.bmc-val-n  { flex: 0 0 52px; }
.bmc-best-n { flex: 0 0 62px; }

/* ── Goals/Cards/1X2 Market — wide layout column widths ──────────────────── */
.bmc-lbl-w  { flex: 0 0 52px; }
.bmc-cell-w { flex: 1; }
.bmc-val-w  { flex: 0 0 58px; }
.bmc-best-w { flex: 0 0 76px; }

/* ── Player Goals/Cards Market — narrow layout ────────────────────────────── */
.bmc-lbl-np  { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bmc-cell-np { flex: 0 0 56px; }
.bmc-best-np { flex: 0 0 62px; }

/* ── Player Goals/Cards Market — wide layout ──────────────────────────────── */
.bmc-lbl-wp  { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bmc-cell-wp { flex: 0 0 80px; }
.bmc-val-wp  { flex: 0 0 58px; }
.bmc-best-wp { flex: 0 0 76px; }

/* ── Shared stat-bar and stat-row layout (Referee Profile, Player Discipline, Trajectory) ── */

.stat-bar-track { flex: 1; background: #1a1a1a; height: 5px; border-radius: 3px; margin: 0 10px; overflow: hidden; }
.stat-bar-fill  { height: 100%; border-radius: 3px; transition: width 0.45s ease-out; }

.stat-row       { display: flex; align-items: center; padding: 5px 0; margin-bottom: 4px; }
.stat-row-icon  { width: 36px; display: flex; align-items: center; flex-shrink: 0; }
.stat-row-label { font-size: var(--t-data); color: #888; flex: 1; min-width: 60px; }
.stat-row-val   { font-weight: 600; color: #fff; font-size: var(--t-body); width: 36px; text-align: right; flex-shrink: 0; }
.stat-row-val--wide { width: 40px; }

.stat-section-hdr { font-weight: 600; color: #fff; font-size: var(--t-data); padding-bottom: 8px; }
.stat-lbl         { font-size: var(--t-data); color: #888; }
.col-muted        { color: #888; }

/* Card icons */
.card-yc             { width: 10px; height: 14px; background: #f1c40f; border-radius: 2px; flex-shrink: 0; }
.card-rc             { width: 10px; height: 14px; background: #e74c3c; border-radius: 2px; flex-shrink: 0; }
.card-icon-inline    { display: inline-block; vertical-align: middle; }
.card-icon-justify-end { justify-self: end; }

/* Player / team discipline column overrides */
.col-num-card { flex: none; width: 22px; text-align: center; }
.col-val-yc   { font-weight: 600; color: #f1c40f; }
.col-val-rc   { font-weight: 600; color: #e74c3c; }

/* Correct score module footer */
.cs-footer { font-size: var(--t-label); color: #666; padding-top: 6px; text-align: center; }

/* ── Referee With Teams layout ── */
.rwt-wrapper     { display: flex; flex-direction: column; width: 100%; min-height: 100%; }
.rwt-body        { display: flex; flex: 1; min-height: 0; align-items: center; }
.rwt-donut-col   { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; }
.rwt-stats-col   { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 10px; margin-left: 20px; padding-right: 10px; }
.rwt-stats-grid  { display: grid; grid-template-columns: 1fr 14px 1fr; gap: 6px; align-items: center; }
.rwt-stat-lbl    { font-size: var(--t-data); color: #888; text-align: center; }
.rwt-stat-center { display: flex; justify-content: center; }
.rwt-stat-val    { font-weight: 600; color: #fff; font-size: var(--t-body); min-width: 18px; text-align: center; }
.rp-hdr-offset   { flex-shrink: 0; margin-top: -6px; }
.ref-pen-icon    { flex-shrink: 0; justify-self: end; }

/* ── Movement modules ─────────────────────────────────────────────────────── */
.bmm-stats {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 15px 6px;
  flex-shrink: 0;
}
.bmm-stat-lbl {
  font-size: var(--t-label);
  color: #5a7a8a;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.bmm-open-val,
.bmm-now-val {
  font-size: var(--t-title);
  color: var(--bm-text);
  font-weight: 700;
}
.bmm-arrow {
  font-size: var(--t-body);
  flex-shrink: 0;
}
.bmm-move {
  margin-left: auto;
  text-align: right;
}
.bmm-move-val {
  font-size: var(--t-data);
  font-weight: 700;
}
.bmm-label {
  padding: 0 15px 4px;
  flex-shrink: 0;
}
.bmm-label-txt {
  font-size: var(--t-label);
  color: #7a9db8;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.bmm-chart {
  flex: 1;
  min-height: 0;
  padding: 0 15px 8px;
}

/* ── Injury / Doubtful ────────────────────────────────────────────────────── */
.inj-badge {
  display: inline-block;
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 2px 6px;
  border-radius: 3px;
  flex-shrink: 0;
}
.bm-updated {
  font-size: var(--t-label);
  color: #888;
  margin-bottom: 6px;
}
.bm-empty {
  font-size: var(--t-data);
  color: #5a7a8a;
  padding: 8px 0;
}

/* ── Widget fetch states (loading / error) ────────────────────────────────────
   WidgetSkeleton.tsx: a faint outline shaped like the module type that's
   coming, a shimmer sweeping across it (each piece a beat after the last), and
   a fade-up when the data lands (.bm-revealed). Only shown pre-data — VRT
   baselines screenshot the loaded state, so these don't move. */
.bm-skeleton {
  --skel-a: rgba(255, 255, 255, 0.05);
  --skel-b: rgba(255, 255, 255, 0.13);
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}
[data-theme="light"] .bm-skeleton {
  --skel-a: rgba(0, 0, 0, 0.05);
  --skel-b: rgba(0, 0, 0, 0.11);
}
.skel {
  border-radius: 4px;
  background: linear-gradient(90deg, var(--skel-a) 0%, var(--skel-b) 50%, var(--skel-a) 100%);
  background-size: 200% 100%;
  animation: bm-skel-shimmer 1.4s ease-in-out infinite;
}
@keyframes bm-skel-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes bm-skel-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
/* The wave: each row starts its shimmer a little after the one before. */
.bm-skeleton > :nth-child(2) > .skel, .bm-skeleton > :nth-child(2).skel { animation-delay: 0.08s; }
.bm-skeleton > :nth-child(3) > .skel, .bm-skeleton > :nth-child(3).skel { animation-delay: 0.16s; }
.bm-skeleton > :nth-child(4) > .skel { animation-delay: 0.24s; }
.bm-skeleton > :nth-child(5) > .skel { animation-delay: 0.32s; }
.bm-skeleton > :nth-child(6) > .skel { animation-delay: 0.4s; }
.bm-skeleton > :nth-child(7) > .skel { animation-delay: 0.48s; }

/* Rows: tables (a header bar, then name + value) and stat bars (label, track, value). */
.skel-row { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.skel-head { height: 10px; width: 100%; opacity: 0.7; flex-shrink: 0; }
.skel-team { flex: 1; height: 11px; }
.skel-value { width: 14%; max-width: 42px; height: 11px; flex-shrink: 0; }
.skel-label { width: 26%; height: 10px; flex-shrink: 0; }
.skel-track { flex: 1; height: 8px; border-radius: 4px; }

/* Donuts: two rings side by side. */
.skel-donuts { flex: 1; display: flex; align-items: center; justify-content: space-around; gap: 12px; min-height: 0; }
.skel-donut {
  height: min(100%, 110px); aspect-ratio: 1; border-radius: 50%;
  -webkit-mask: radial-gradient(circle, transparent 52%, #000 53%);
  mask: radial-gradient(circle, transparent 52%, #000 53%);
}

/* Form badges: a label, then a row of square badges. */
.skel-badges { display: flex; flex-direction: column; gap: 6px; }
.skel-badges > .skel-label { width: 34%; }
.skel-badge-row { display: flex; gap: 4px; }
.skel-box { flex: 1 1 0; max-width: 22px; aspect-ratio: 1; border-radius: 3px; }
.skel-badge-row > :nth-child(2) { animation-delay: 0.08s; }
.skel-badge-row > :nth-child(3) { animation-delay: 0.16s; }
.skel-badge-row > :nth-child(4) { animation-delay: 0.24s; }
.skel-badge-row > :nth-child(5) { animation-delay: 0.32s; }

/* Charts: axes on the left and bottom; a line, or columns. */
.skel-chart {
  flex: 1; min-height: 0; position: relative;
  border-left: 1px solid var(--skel-b); border-bottom: 1px solid var(--skel-b);
}
.skel-line-svg { position: absolute; inset: 8% 0 8% 0; width: 100%; height: 84%; animation: bm-skel-pulse 1.4s ease-in-out infinite; }
.skel-line-svg path { fill: none; stroke: var(--skel-b); stroke-width: 2; vector-effect: non-scaling-stroke; }
.skel-columns { display: flex; align-items: flex-end; justify-content: space-around; gap: 8%; padding: 0 6%; }
.skel-col { flex: 1; border-radius: 3px 3px 0 0; }
.skel-col:nth-child(2) { animation-delay: 0.08s; }
.skel-col:nth-child(3) { animation-delay: 0.16s; }
.skel-col:nth-child(4) { animation-delay: 0.24s; }
.skel-col:nth-child(5) { animation-delay: 0.32s; }
.skel-col:nth-child(6) { animation-delay: 0.4s; }

/* Heatmap: a 5×5 grid of cells. */
.skel-grid {
  flex: 1; min-height: 0; display: grid; gap: 3px;
  grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(5, 1fr);
}
.skel-cell { border-radius: 2px; }
.skel-cell:nth-child(5n + 2) { animation-delay: 0.08s; }
.skel-cell:nth-child(5n + 3) { animation-delay: 0.16s; }
.skel-cell:nth-child(5n + 4) { animation-delay: 0.24s; }
.skel-cell:nth-child(5n) { animation-delay: 0.32s; }

/* Radial (Match States): concentric rings, pulsing. */
.skel-radial {
  flex: 1; min-height: 0; position: relative; align-self: center;
  height: min(100%, 160px); aspect-ratio: 1;
  animation: bm-skel-pulse 1.4s ease-in-out infinite;
}
.skel-ring { position: absolute; inset: 0; border: 2px solid var(--skel-b); border-radius: 50%; }
.skel-ring-inner { inset: 28%; }

/* The reveal: the real content fades up from mostly visible as the data lands. */
.module-body.bm-revealed > * { animation: bm-reveal 0.32s ease-out; }
@keyframes bm-reveal { from { opacity: 0.25; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .skel, .skel-line-svg, .skel-radial, .module-body.bm-revealed > * { animation: none; }
}

/* ── "Loading your board" (BoardLoading.tsx) ─────────────────────────────────
   The empty canvas while the saved board is on its way: a little bento box
   builds itself — tiles spring in one by one with the skeleton shimmer, the
   last lit green like the drop ghost — then clears and starts again. Only
   after the intro (html.intro-done, main.js); fades out when the board lands. */
.board-loading {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s ease, visibility 0s linear 0.35s;
}
.board-loading.show {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.35s ease, visibility 0s;
}
html:not(.intro-done) .board-loading { display: none; }
.board-loading:not(.show) * { animation-play-state: paused; }
.board-loading-box {
  --bl-a: #262626;
  --bl-b: #3a3a3a;
  display: grid;
  grid-template-columns: repeat(3, 38px);
  grid-template-rows: repeat(2, 38px);
  gap: 6px;
}
.bl-tile {
  border-radius: 7px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  background: linear-gradient(90deg, var(--bl-a) 0%, var(--bl-b) 50%, var(--bl-a) 100%);
  background-size: 200% 100%;
  opacity: 0;
  animation: bl-build 2.8s cubic-bezier(0.34, 1.4, 0.64, 1) infinite,
             bm-skel-shimmer 1.4s ease-in-out infinite;
}
.bl-wide { grid-column: 1 / 3; grid-row: 1; }
.bl-tall { grid-column: 3; grid-row: 1 / 3; animation-delay: 0.16s, 0.16s; }
.bl-a    { grid-column: 1; grid-row: 2; animation-delay: 0.32s, 0.32s; }
.bl-b    {
  grid-column: 2; grid-row: 2; animation-delay: 0.48s, 0.48s;
  --bl-a: rgba(46, 204, 113, 0.16);
  --bl-b: rgba(46, 204, 113, 0.34);
  border: 2px solid #2ecc71;
}
@keyframes bl-build {
  0%       { opacity: 0; transform: scale(0.5); }
  14%      { opacity: 1; transform: scale(1.08); }
  22%      { transform: scale(0.97); }
  28%, 76% { opacity: 1; transform: scale(1); }
  90%, 100% { opacity: 0; transform: scale(0.85); }
}
.board-loading-text {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #888;
}
.bl-dots { display: inline-flex; gap: 3px; }
.bl-dots i {
  width: 4px; height: 4px; border-radius: 50%;
  background: #2ecc71;
  animation: bl-dot 1.2s ease-in-out infinite;
}
.bl-dots i:nth-child(2) { animation-delay: 0.15s; }
.bl-dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes bl-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.35; }
  30%           { transform: translateY(-4px); opacity: 1; }
}
[data-theme="light"] .board-loading-box { --bl-a: #e2e2e6; --bl-b: #f2f2f5; }
[data-theme="light"] .bl-tile { border-color: rgba(0, 0, 0, 0.06); }
[data-theme="light"] .board-loading-text { color: #666; }
@media (prefers-reduced-motion: reduce) {
  .bl-tile { animation: none; opacity: 1; }
  .bl-dots i { animation: none; opacity: 1; }
}

.bm-error {
  font-size: var(--t-data);
  color: #5a7a8a;
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.bm-retry {
  font-size: var(--t-label);
  color: var(--text-main, #eee);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  padding: 3px 10px;
  cursor: pointer;
}
.bm-retry:hover { background: rgba(255, 255, 255, 0.14); }
[data-theme="light"] .bm-retry {
  color: #222;
  background: rgba(0, 0, 0, 0.06);
  border-color: rgba(0, 0, 0, 0.15);
}
[data-theme="light"] .bm-retry:hover { background: rgba(0, 0, 0, 0.12); }

/* ── News & Sentiment ─────────────────────────────────────────────────────── */
.ns-top-pad { padding-top: 4px; }
.ns-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.ns-item-bar {
  width: 3px;
  height: 100%;
  min-height: 28px;
  border-radius: 2px;
  flex-shrink: 0;
  align-self: stretch;
}
.ns-item-text {
  font-size: var(--t-data);
  color: var(--bm-text);
  line-height: 1.35;
}
.ns-item-time {
  font-size: var(--t-label);
  color: #888;
  margin-top: 2px;
}

/* ── Value Indicator ──────────────────────────────────────────────────────── */
.vi-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.vi-hdr-mkt  { flex: 0 0 46px; }
.vi-hdr-out  { flex: 1; }
.vi-hdr-num  { flex: 0 0 40px; text-align: right; }
.vi-hdr-num--pl { padding-right: 4px; }
.vi-hdr-edge { flex: 0 0 46px; text-align: right; }
.vi-row {
  display: flex;
  align-items: center;
  padding: 8px 15px;
  border-bottom: 1px solid var(--bm-border);
  font-size: var(--t-data);
}
.vi-row--alt { background: rgba(255,255,255,0.03); }
.vi-mkt  { flex: 0 0 46px; font-size: var(--t-label); color: #7a9db8; font-weight: 600; text-transform: uppercase; }
.vi-out  { flex: 1; color: var(--bm-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vi-num  { flex: 0 0 40px; text-align: right; color: var(--bm-text); font-weight: 600; }
.vi-edge { flex: 0 0 46px; text-align: right; font-weight: 700; }

/* ── Margin Calculator ────────────────────────────────────────────────────── */
.mc-badge-col {
  flex: 0 0 34px;
  display: flex;
  align-items: center;
}
.mc-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  padding: 2px 5px;
  min-width: 24px;
  height: 18px;
}
.mc-badge-txt {
  font-size: var(--t-label);
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.04em;
}
.mc-cell {
  flex: 1;
  text-align: right;
  font-size: var(--t-data);
}
.mc-spacer { flex: 0 0 34px; }

/* ── Tour overlay ─────────────────────────────────────────────────────────── */
#tour-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 8000;
  pointer-events: auto;
  background: rgba(0, 0, 0, 0.18);
}
#tour-overlay.active { display: block; }

#tour-panel {
  position: fixed;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%);
  width: 500px;
  max-width: calc(100vw - 32px);
  background: #1c1c1c;
  border: 1px solid #383838;
  border-radius: 14px;
  padding: 22px 56px 20px 24px;
  pointer-events: all;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.7);
}

#tour-step-indicator {
  font-size: var(--t-label);
  color: #555;
  margin-bottom: 8px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

#tour-text {
  margin: 0 0 18px;
  font-size: 0.85rem;
  color: #ccc;
  line-height: 1.55;
}

#tour-cancel {
  position: absolute;
  top: 10px;
  right: 10px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.12);
  color: #888;
  font-size: 1.5rem;
  cursor: pointer;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 8px;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
  font-family: inherit;
}
#tour-cancel:hover { color: #e74c3c; background: rgba(231,76,60,0.12); border-color: rgba(231,76,60,0.3); }

.tour-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
}

#tour-replay {
  display: none;
  background: rgba(255,255,255,0.07);
  color: #888;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px;
  padding: 9px 18px;
  font-size: var(--t-body);
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  transition: opacity 0.15s;
}
#tour-replay:hover:not(:disabled) { opacity: 0.75; }
#tour-replay:disabled { opacity: 0.2; cursor: default; pointer-events: none; }

#tour-next {
  background: #2ecc71;
  color: #000;
  border: none;
  border-radius: 8px;
  padding: 9px 20px;
  min-width: 90px;
  font-size: var(--t-body);
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, opacity 0.15s;
}
#tour-next:hover { background: #27ae60; }
#tour-next:disabled { opacity: 0.2; cursor: default; pointer-events: none; }

/* Fake cursor */
#tour-cursor {
  display: none;
  position: fixed;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(46, 204, 113, 0.25);
  border: 2px solid rgba(46, 204, 113, 0.9);
  box-shadow: 0 0 14px rgba(46, 204, 113, 0.5);
  pointer-events: none;
  z-index: 8500;
  transform: translate(-50%, -50%);
  transition: left 0.6s cubic-bezier(0.4, 0, 0.2, 1),
              top  0.6s cubic-bezier(0.4, 0, 0.2, 1),
              background 0.2s, border-color 0.2s, box-shadow 0.2s;
}
#tour-cursor.grabbing {
  background: rgba(241, 196, 15, 0.25);
  border-color: rgba(241, 196, 15, 0.9);
  box-shadow: 0 0 14px rgba(241, 196, 15, 0.5);
  transform: translate(-50%, -50%) scale(1.2);
}
#tour-cursor.pointer {
  background: rgba(52, 152, 219, 0.25);
  border-color: rgba(52, 152, 219, 0.9);
  box-shadow: 0 0 14px rgba(52, 152, 219, 0.5);
}
#tour-cursor.active { display: block; }

@media (max-width: 768px) {
  #tour-panel {
    bottom: 64px;
    border-radius: 12px;
    padding: 18px 18px 16px;
    max-width: 80%;
  }
  #tour-cancel {
    position: static;
    float: right;
    margin: 0 0 8px 12px;
  }
  #tour-overlay {
    transition: background 0.3s ease;
  }
  #tour-overlay.dimmed {
    background: rgba(0, 0, 0, 0.72);
  }
  .tour-actions {
    gap: 8px;
  }
  #tour-replay,
  #tour-next {
    padding: 9px 14px;
    min-width: 0;
  }
}

/* ==========================================================================
   Auth overlay (WS-D D2′) — the login-only sign-in gate that covers the
   dashboard until the user is authenticated (admin-provisioned accounts; no
   sign-up/reset UI). Theme-aware via the shared tokens (works in dark + light).
   Green accent = #2ecc71 (the app-wide accent).
   ========================================================================== */

.auth-overlay {
  position: fixed;
  inset: 0;
  z-index: 100000; /* above every legacy layer (max legacy z-index is 9999) */
  background: var(--bg-color);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 48px 20px;
}

/* Holding state while the Amplify session resolves — same canvas, no content,
   so the dashboard never flashes before the gate decides. */
.auth-overlay-loading {
  display: block;
}

.auth-overlay-inner {
  width: 100%;
  max-width: 380px;
  margin: auto;
}

.auth-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 28px 26px 26px;
  box-shadow: 0 12px 40px var(--shadow-lg);
}

.auth-brand {
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: var(--t-title);
  color: var(--text-color);
  margin-bottom: 22px;
}
.auth-brand-o {
  color: #2ecc71;
}

.auth-title {
  font-size: var(--t-hero);
  font-weight: 600;
  color: var(--text-color);
  margin: 0 0 4px;
}
.auth-subtitle {
  font-size: var(--t-title);
  color: var(--text-muted);
  margin: 0 0 20px;
  line-height: 1.4;
}

.auth-field {
  display: block;
  margin-bottom: 14px;
}
.auth-field-label {
  display: block;
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.auth-input {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 12px;
  background: var(--bg-input);
  border: 1.5px solid var(--border-color);
  border-radius: 8px;
  color: var(--text-color);
  font-family: inherit;
  font-size: var(--t-title);
  transition: border-color var(--transition-base);
}
.auth-input:focus {
  outline: none;
  border-color: #2ecc71;
}
/* Password show/hide eye (sign-in). The input keeps right padding so typed text
   never runs under the icon. Scoped to .auth-* — no other screen uses these. */
.auth-input-wrap {
  position: relative;
  display: block;
}
.auth-input-revealable {
  padding-right: 44px;
}
.auth-reveal {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: none;
  border: none;
  border-radius: 6px;
  /* One fixed grey, no hover change (as BenCat): a hover brighten went white in
     dark mode and vanished on the light-blue browser-autofilled field. */
  color: var(--text-muted);
  cursor: pointer;
}

.auth-submit {
  width: 100%;
  margin-top: 8px;
  padding: 12px;
  background: #2ecc71;
  color: #08130c;
  border: none;
  border-radius: 8px;
  font-family: inherit;
  font-size: var(--t-title);
  font-weight: 600;
  cursor: pointer;
  transition: opacity var(--transition-base), filter var(--transition-base);
}
.auth-submit:hover:not(:disabled) {
  filter: brightness(1.06);
}
.auth-submit:disabled {
  opacity: 0.6;
  cursor: default;
}

.auth-footer {
  margin-top: 22px;
  text-align: center;
  font-size: var(--t-data);
  color: var(--text-muted);
}

.auth-notice {
  padding: 9px 12px;
  border-radius: 8px;
  font-size: var(--t-data);
  margin-bottom: 14px;
  line-height: 1.4;
}
/* Soft, restrained error (the no-red rule is scoped to the password checklist;
   a failed sign-in still needs a clear error tone). */
.auth-notice-error {
  background: rgba(231, 76, 60, 0.12);
  border: 1px solid rgba(231, 76, 60, 0.4);
  color: var(--c-loss);
}

/* ── Movement History flip (movement modules; see movementHistoryConfig.ts) ──
   Ported from the bento-movement-history prototype. */
  /* Its own row, below the bookmaker/team/opponent controls bar and above the
     chart — kept separate from .history-sub-controls so it doesn't compete
     with those selects for space, and reads as "how to view the chart below"
     rather than another filter alongside the rest. */
  .history-view-row {
    display: flex;
    justify-content: flex-start;
    padding: 6px 15px;
  }
  /* Segmented button group — used where switching options is "flip through
     lenses on the same data" rather than "pick one thing from a list", so a
     dropdown (this app's universal filter control) would hide the options
     instead of inviting comparison. */
  .history-view-btns {
    display: inline-flex;
    gap: 6px;
    flex-shrink: 0;
  }
  .history-view-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    color: #aaa;
    background: #1a1a1a;
    border: 1px solid #333;
    border-radius: 3px;
    cursor: pointer;
    flex-shrink: 0;
  }
  .history-view-btn:hover { color: #ddd; }
  .history-view-btn svg { width: 11px; height: 11px; }
  .history-view-btn.active { color: #2ecc71; background: rgba(46, 204, 113, 0.12); }

  .module-history {
    font-size: var(--t-title);
    line-height: 1;
    color: #666;
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    transition: color var(--transition-fast);
    display: flex;
    align-items: center;
  }
  .module-history * { cursor: pointer; }
  .module-history:hover { color: #2ecc71; }

  /* ── Movement History flip (pilot: Winner (1x2) - Movement) ────────────────
     Reuses the exact 3D flip mechanic already proven elsewhere in this app —
     see the shared discipline note in CLAUDE.md re: not inventing a second
     pattern for the same interaction. */
  .module-flip-outer {
    flex: 1;
    min-height: 0;
    position: relative;
    perspective: 1600px;
    /* Clipping/rounding lives here on the static wrapper, not on the rotating
       faces below — combining backface-visibility:hidden with overflow:hidden
       and border-radius on the SAME element is a known cross-browser bug that
       makes the front face bleed through during rotation instead of hiding. */
    border-radius: var(--radius);
    overflow: hidden;
  }
  .module-flip-inner {
    position: absolute;
    inset: 0;
    transform-style: preserve-3d;
    /* Same bounce/overshoot curve used elsewhere in this app (pin animation,
       fixture-select enter, mobile module pop-in) for a consistent "premium
       pop" feel rather than a flat mechanical ease. */
    transition: transform 600ms cubic-bezier(0.34, 1.56, 0.64, 1);
  }
  .placed-module.history-flipped .module-flip-inner {
    transform: rotateY(180deg);
  }
  .module-flip-front,
  .module-flip-back {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    display: flex;
    flex-direction: column;
    background: linear-gradient(145deg, #333333 0%, #1a1a1a 100%);
  }
  .module-flip-back {
    transform: rotateY(180deg);
  }
  .module-flip-back .module-header {
    justify-content: space-between;
  }
  .module-history-back {
    font-size: var(--t-title);
    line-height: 1;
    color: #666;
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    transition: color var(--transition-fast);
    display: flex;
    align-items: center;
  }
  .module-history-back * { cursor: pointer; }
  .module-history-back:hover { color: #2ecc71; }

  .history-sub-controls select {
    min-width: 0;
    flex: 1 1 auto;
  }
  .history-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 8px 10px 10px;
  }
  .mh-chart {
    flex: 1;
    min-height: 0;
    position: relative;
  }
  .mh-line {
    fill: none;
    stroke: #666;
    stroke-width: 1.5;
    opacity: 0.55;
    transition: stroke 0.2s ease, stroke-width 0.2s ease, opacity 0.2s ease;
  }
  .mh-line.mh-line-active {
    stroke: #6fcf97;
    stroke-width: 2.5;
    opacity: 1;
  }

[data-theme="light"] .history-view-btn { color: #555; background: var(--bg-input); border-color: var(--border-color); }
[data-theme="light"] .history-view-btn:hover { color: #222; }
[data-theme="light"] .history-view-btn.active { color: #218c4c; background: rgba(33, 140, 76, 0.12); }
[data-theme="light"] .module-history { color: var(--text-dim); }
[data-theme="light"] .module-history:hover { color: #218c4c; }
[data-theme="light"] .module-history-back { color: var(--text-dim); }
[data-theme="light"] .module-history-back:hover { color: #218c4c; }
[data-theme="light"] .module-flip-front,
[data-theme="light"] .module-flip-back { background: linear-gradient(150deg, #f4f4f8 0%, #dcdce0 100%); }
[data-theme="light"] .mh-line { stroke: #999; }
[data-theme="light"] .mh-line.mh-line-active { stroke: #218c4c; }
.betting-module .history-view-row {
  background-color: #0d1520;
}
.betting-module .history-view-btn {
  background: #0e1a28;
  border-color: #1e3048;
  color: #a8c0d0;
}
.betting-module .history-view-btn.active {
  background: rgba(46, 204, 113, 0.15);
  border-color: #2ecc71;
}
.history-body .mh-wrapper { flex: 1; min-height: 0; }
/* The front face's line / player, shown beside the view buttons. */
.history-view-row { align-items: center; gap: 10px; }
.history-view-label {
  margin-left: auto;
  color: #999;
  font-size: var(--t-label);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mh-empty {
  margin: auto;
  color: #777;
  font-size: var(--t-data);
}

/* Market table rows drive their paired movement module on click (main.js). */
.module-body .bm-row[data-line],
.module-body .bm-row[data-player] { cursor: pointer; }
