/* Loft Links — page chrome. The canvas draws the course; everything here is
   the clubhouse around it. Palette follows the rest of the site (slate glass,
   one accent) with the accent swung to a sky blue, so the 3D game and the flat
   one next door are visibly siblings rather than twins. */

:root {
    --bg-1: #06121e;
    --bg-2: #0b1c2c;
    --panel: rgba(18, 34, 50, 0.58);
    --panel-border: rgba(125, 211, 252, 0.18);
    --ink: #eaf6ff;
    --ink-dim: #9fb6c9;
    --accent: #38bdf8;
    --accent-soft: rgba(56, 189, 248, 0.14);
    --over: #fca5a5;
    --under: #86efac;
    --gold: #fbbf24;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    min-height: 100%;
}

body {
    font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    color: var(--ink);
    background: linear-gradient(140deg, var(--bg-1) 0%, var(--bg-2) 100%) fixed;
    -webkit-font-smoothing: antialiased;
    padding: 1rem 1rem 3rem;
}

body::before {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    background:
        radial-gradient(circle at 12% 10%, rgba(56, 189, 248, 0.12), transparent 44%),
        radial-gradient(circle at 90% 80%, rgba(134, 239, 172, 0.08), transparent 46%);
}

.wrap {
    position: relative;
    z-index: 1;
    max-width: 1100px;
    margin: 0 auto;
}

/* ── header ─────────────────────────────────────────────────────────────── */

.topbar {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    margin-bottom: 1rem;
}

.home-link {
    flex: none;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    text-decoration: none;
    font-size: 1.1rem;
    color: var(--ink);
    background: var(--panel);
    border: 1px solid var(--panel-border);
    transition: background 0.2s, transform 0.2s;
}

.home-link:hover { background: var(--accent-soft); transform: translateX(-2px); }

.brand { min-width: 0; }

.title {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.title span { color: var(--accent); }

.tagline {
    margin: 0.1rem 0 0;
    font-size: 0.85rem;
    color: var(--ink-dim);
    font-weight: 300;
}

.topbar-actions {
    position: relative;
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 0.5rem;
}

/* Wide enough for all of them and the menu is not a menu: `display: contents`
   drops the wrapper out of the layout and its chips sit in the topbar row
   exactly as they used to. The compact rules further down put the wrapper
   back and turn it into a panel. */
.topbar-menu { display: contents; }
.chip-menu { display: none; }

/* Chips are icons in the row and words in the panel — a lone "?" reads fine
   next to five siblings and reads like nothing in a list of five items. */
.chip-text { display: none; }

button.chip {
    font: inherit;
    font-size: 0.85rem;
    color: var(--ink);
    background: var(--panel);
    border: 1px solid var(--panel-border);
    border-radius: 10px;
    padding: 0.45rem 0.8rem;
    cursor: pointer;
    transition: background 0.18s, border-color 0.18s, transform 0.18s;
}

button.chip:hover { background: var(--accent-soft); border-color: rgba(125, 211, 252, 0.45); }
button.chip:active { transform: translateY(1px); }
button.chip.on { background: var(--accent); color: #06212f; border-color: transparent; }

/* ── scoreboard ─────────────────────────────────────────────────────────── */

.scoreboard {
    display: grid;
    grid-template-columns: 2.4fr repeat(5, 1fr);
    gap: 0.6rem;
    background: var(--panel);
    border: 1px solid var(--panel-border);
    border-radius: 16px;
    padding: 0.85rem 1rem;
    margin-bottom: 0.9rem;
    backdrop-filter: blur(10px);
}

.stat { min-width: 0; }

.stat-label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--ink-dim);
    margin-bottom: 0.15rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stat-value {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.stat-value.under { color: var(--under); }
.stat-value.over { color: var(--over); }
.stat-value.level { color: var(--accent); }

/* The name asks for the hole card back, so it is a button — one that has to
   keep looking like the heading it was. */
.hole-name {
    display: block;
    max-width: 100%;
    font: inherit;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--ink);
    background: none;
    border: 0;
    padding: 0;
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.15s;
}

.hole-name:hover,
.hole-name:focus-visible { color: var(--accent); }

/* The sky under the hole's name: what the weather is doing, and a button
   that changes it. Quiet enough to read as a caption, and it only stops
   looking like one when you hover it. */
.hole-sky {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    margin-top: 0.25rem;
    padding: 0.1rem 0.4rem 0.1rem 0.3rem;
    border: 1px solid transparent;
    border-radius: 999px;
    background: none;
    color: var(--ink-dim);
    font: inherit;
    font-size: 0.74rem;
    font-weight: 400;
    line-height: 1.3;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.hole-sky:hover,
.hole-sky:focus-visible {
    background: rgba(255, 255, 255, 0.06);
    border-color: var(--panel-border);
    color: var(--ink);
}

.sky-wind {
    font-size: 0.68rem;
    opacity: 0.75;
    font-variant-numeric: tabular-nums;
}

/* ── stage ──────────────────────────────────────────────────────────────── */

.stage {
    position: relative;
    border-radius: 18px;
    overflow: hidden;
    border: 1px solid var(--panel-border);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
    line-height: 0;
    background: #0a1622;
}

canvas {
    display: block;
    width: 100%;
    /* Tall enough to be the thing you are looking at. The floor keeps it
       playable on a short laptop, the ceiling stops it turning into a
       letterbox on a big desktop monitor. */
    height: clamp(380px, calc(100dvh - 210px), 820px);
    touch-action: none;
    cursor: grab;
}

canvas:active { cursor: grabbing; }

/* ── clubs and power ────────────────────────────────────────────────────── */

/* The bar along the bottom of the stage is where a shot is loaded and played:
   the meter on the left, Swing and the two aim nudges on the right. It is the
   only part of the overlay that takes a press, so everything in it opts back
   into pointer events one control at a time. */
.controls {
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 12px;
    padding-left: min(26%, 220px);   /* the bag stands here */
    display: flex;
    align-items: flex-end;
    gap: 0.9rem;
    line-height: 1.2;
    pointer-events: none;
}

.controls .power { flex: 1 1 auto; min-width: 0; }

.shot-actions {
    flex: none;
    display: flex;
    align-items: stretch;
    gap: 0.4rem;
    pointer-events: auto;
}

.swing {
    font: inherit;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    color: #06212f;
    background: var(--accent);
    border: 0;
    border-radius: 12px;
    padding: 0.6rem 1.5rem;
    cursor: pointer;
    box-shadow: 0 8px 24px rgba(56, 189, 248, 0.35);
    transition: transform 0.15s, box-shadow 0.15s, opacity 0.15s;
}

.swing:hover:not(:disabled) { transform: translateY(-1px); }
.swing:active:not(:disabled) { transform: translateY(1px); }

/* Nothing loaded, or the ball is still rolling: the button says so rather
   than swallowing the press. */
.swing:disabled {
    cursor: default;
    opacity: 0.45;
    box-shadow: none;
    background: rgba(255, 255, 255, 0.22);
    color: rgba(234, 246, 255, 0.9);
}

.aim-nudge {
    font: inherit;
    font-size: 1.15rem;
    line-height: 1;
    width: 40px;
    color: var(--ink);
    background: rgba(6, 20, 32, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 12px;
    cursor: pointer;
    transition: background 0.15s;
}

.aim-nudge:hover { background: rgba(56, 189, 248, 0.3); }
.aim-nudge:active { background: var(--accent); color: #06212f; }

/* The club picker is the modelled bag in the corner of the canvas, so the
   caption text is no longer shown — kept only for screen readers. */
.club-hint {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── the club picker ────────────────────────────────────────────────────── */

/* The clubs themselves are modelled and drawn on the canvas; this is the part
   that has to be readable, so it is text. It sits above the row of clubs and
   dims the course behind them. */
.picker {
    position: absolute;
    inset: 0;
    display: grid;
    align-content: start;
    justify-items: center;
    gap: 0.18rem;
    padding: clamp(0.8rem, 5vh, 2.6rem) 1rem 0;
    text-align: center;
    background: radial-gradient(ellipse at 50% 62%, rgba(4, 14, 24, 0.1), rgba(4, 14, 24, 0.62) 70%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
}

.picker.show { opacity: 1; }

.picker-title {
    margin: 0;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--accent);
}

.picker-name {
    margin: 0.15rem 0 0;
    font-size: clamp(1.4rem, 3.4vw, 2rem);
    line-height: 1.15;
    font-weight: 800;
    letter-spacing: -0.02em;
    text-shadow: 0 4px 24px rgba(0, 0, 0, 0.65);
}

.picker-blurb {
    margin: 0.1rem 0 0;
    max-width: 30ch;
    /* Two lines whether the blurb needs two or one: the clubs are laid out in
       whatever room this panel leaves them, and a panel that changed height
       from club to club would shuffle the row every time you looked at a
       different one. */
    min-height: 2.7em;
    font-size: 0.88rem;
    font-weight: 300;
    line-height: 1.35;
    color: var(--ink-dim);
}

.picker-stats {
    margin: 0.35rem 0 0;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    color: var(--accent);
}

.picker-stats b { color: var(--ink); font-weight: 700; }

@media (max-width: 640px) {
    .picker-blurb { font-size: 0.78rem; }
}

/* ── compact overlay, for when the scoreboard is off screen ─────────────── */

/* Hole, par, strokes and distance — the four figures that move during a
   shot — on one line, with everything that merely describes the hole one tap
   underneath. The line itself is the button that opens the rest. */
.stage-hud {
    position: absolute;
    top: 12px;
    left: 12px;
    display: none;
    max-width: calc(100% - 24px);
    border-radius: 12px;
    color: var(--ink);
    background: rgba(6, 20, 32, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.14);
    backdrop-filter: blur(6px);
    line-height: 1.3;
    overflow: hidden;
    transition: opacity 0.2s;
}

.hud-line {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.35rem 0.6rem;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
    text-align: left;
}

.hud-line span + span { padding-left: 0.6rem; border-left: 1px solid rgba(255, 255, 255, 0.15); }

.hud-caret {
    border-left: 0 !important;
    padding-left: 0.1rem !important;
    font-size: 0.7rem;
    color: var(--ink-dim);
    transition: transform 0.2s;
}

.stage-hud.open .hud-caret { transform: rotate(180deg); }

.hud-detail {
    padding: 0 0.65rem 0.55rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    max-width: 34ch;
}

.hud-name { font-size: 0.92rem; font-weight: 800; letter-spacing: -0.01em; margin-top: 0.4rem; }

.hud-blurb {
    font-size: 0.76rem;
    font-weight: 300;
    color: var(--ink-dim);
    line-height: 1.35;
    margin-top: 0.1rem;
}

.hud-sky {
    margin-top: 0.4rem;
    font: inherit;
    font-size: 0.74rem;
    color: var(--ink-dim);
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--panel-border);
    border-radius: 999px;
    padding: 0.15rem 0.55rem;
    cursor: pointer;
    white-space: nowrap;
}

.hud-sky:hover { color: var(--ink); background: rgba(255, 255, 255, 0.12); }

/* Fullscreen is taken on the viewport, so the topbar, the overlay and the
   modals come with it: the same immersive layout the phone gets, on any
   screen. The two spellings are separate rules on purpose — a pseudo-class a
   browser does not know would throw away the whole selector list.  */

.viewport:fullscreen {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background: linear-gradient(140deg, var(--bg-1) 0%, var(--bg-2) 100%);
}

.viewport:fullscreen .topbar {
    flex: none;
    margin: 0;
    padding: 0.55rem 0.8rem;
}

.viewport:fullscreen .scoreboard {
    display: none;
}

.viewport:fullscreen .stage-hud {
    display: block;
}

.viewport:fullscreen .stage {
    flex: 1 1 auto;
    min-height: 0;
    border-radius: 0;
    border: 0;
}

.viewport:fullscreen canvas {
    width: 100%;
    height: 100%;
}

.viewport:-webkit-full-screen {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background: linear-gradient(140deg, var(--bg-1) 0%, var(--bg-2) 100%);
}

.viewport:-webkit-full-screen .topbar {
    flex: none;
    margin: 0;
    padding: 0.55rem 0.8rem;
}

.viewport:-webkit-full-screen .scoreboard {
    display: none;
}

.viewport:-webkit-full-screen .stage-hud {
    display: block;
}

.viewport:-webkit-full-screen .stage {
    flex: 1 1 auto;
    min-height: 0;
    border-radius: 0;
    border: 0;
}

.viewport:-webkit-full-screen canvas {
    width: 100%;
    height: 100%;
}

.ctl-label {
    display: block;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: rgba(234, 246, 255, 0.8);
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.7);
    margin-bottom: 0.25rem;
}

.ctl-label b { color: var(--ink); font-variant-numeric: tabular-nums; }

.power-track {
    position: relative;
    height: 22px;
    pointer-events: auto;
    cursor: pointer;
    touch-action: none;
    border-radius: 11px;
    background: rgba(3, 12, 20, 0.62);
    border: 1px solid rgba(255, 255, 255, 0.2);
    overflow: hidden;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
}

.power-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.power-fill {
    height: 100%;
    width: 0;
    background: var(--accent);
    box-shadow: 0 0 12px currentColor;
    transition: width 0.04s linear;
}

/* Where the swing runs out. Everything past it is the part of the shot most
   likely to end in the water. */
.power-max {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 85%;
    width: 2px;
    background: rgba(255, 255, 255, 0.55);
}

.power-track.hot { border-color: rgba(248, 113, 113, 0.85); }
.power-track.hot .power-fill { animation: powerPulse 0.45s ease-in-out infinite alternate; }

@keyframes powerPulse {
    from { filter: brightness(1); }
    to { filter: brightness(1.45); }
}

/* ── hole-complete banner ───────────────────────────────────────────────── */

.banner {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 0.35rem;
    text-align: center;
    background: rgba(4, 14, 24, 0.55);
    backdrop-filter: blur(3px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s;
    line-height: 1.3;
}

.banner.show { opacity: 1; pointer-events: auto; }

.banner-term {
    font-size: clamp(1.8rem, 6vw, 3rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    text-shadow: 0 6px 30px rgba(0, 0, 0, 0.6);
    animation: pop 0.45s cubic-bezier(0.2, 1.4, 0.4, 1);
}

.banner-term.ace { color: var(--gold); }
.banner-term.great, .banner-term.good { color: var(--under); }
.banner-term.par { color: var(--ink); }
.banner-term.over { color: var(--over); }

@keyframes pop {
    from { transform: scale(0.7); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.banner-detail {
    font-size: 0.95rem;
    color: var(--ink-dim);
    margin-bottom: 0.5rem;
}

.banner button {
    font: inherit;
    font-weight: 600;
    color: #06212f;
    background: var(--accent);
    border: 0;
    border-radius: 12px;
    padding: 0.6rem 1.3rem;
    cursor: pointer;
    transition: transform 0.18s, box-shadow 0.18s;
    box-shadow: 0 8px 24px rgba(56, 189, 248, 0.3);
}

.banner button:hover { transform: translateY(-2px); }

/* ── toast and fallback ─────────────────────────────────────────────────── */

.toast {
    position: absolute;
    left: 50%;
    top: 16px;
    transform: translate(-50%, -10px);
    background: rgba(5, 18, 28, 0.92);
    border: 1px solid var(--panel-border);
    color: var(--ink);
    font-size: 0.85rem;
    line-height: 1.2;
    padding: 0.5rem 0.9rem;
    border-radius: 10px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s, transform 0.2s;
}

.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.bad { border-color: rgba(248, 113, 113, 0.5); color: var(--over); }

/* ── fullscreen prompt ─────────────────────────────────────────────────── */

/* The topbar chip does the same job, but it is one icon among six and easy
   to miss. This says it once, plainly, when a round starts — and stays
   dismissed once waved off, so it never nags. */
/* Parked under the topbar on the side the overlay is not on, so the offer is
   never something to read the hole through. */
.fs-prompt {
    position: absolute;
    right: 12px;
    top: 12px;
    transform: translateY(-10px);
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: rgba(5, 18, 28, 0.92);
    border: 1px solid var(--panel-border);
    color: var(--ink);
    font-size: 0.82rem;
    padding: 0.55rem 0.6rem 0.55rem 0.9rem;
    border-radius: 999px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 5;
}

.fs-prompt.show { opacity: 1; transform: translateY(0); pointer-events: auto; }

.fs-prompt button { font: inherit; cursor: pointer; }

#fs-prompt-go {
    background: var(--accent);
    color: #06212f;
    border: 0;
    border-radius: 999px;
    padding: 0.35rem 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

#fs-prompt-dismiss {
    background: transparent;
    border: 0;
    color: var(--ink-dim);
    width: 26px;
    height: 26px;
    border-radius: 999px;
    font-size: 1.1rem;
    line-height: 1;
}

#fs-prompt-dismiss:hover { color: var(--ink); background: rgba(255, 255, 255, 0.08); }

@media (max-width: 560px) {
    .fs-prompt span { display: none; }
}

.fallback {
    position: absolute;
    inset: 0;
    display: none;
    place-content: center;
    text-align: center;
    padding: 2rem;
    line-height: 1.5;
    font-size: 0.95rem;
    color: var(--ink-dim);
    background: rgba(6, 18, 30, 0.9);
}

.fallback.show { display: grid; }
.fallback b { color: var(--ink); }
.fallback a { color: var(--accent); }

/* ── how to play ────────────────────────────────────────────────────────── */

.help {
    margin-top: 0.9rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.4rem;
    font-size: 0.82rem;
    color: var(--ink-dim);
    font-weight: 300;
}

.help b { color: var(--ink); font-weight: 600; }

/* Keyboard hints are noise on a phone, and the pinch tip is noise on a
   desktop. Switched on the primary pointer rather than on width, so a small
   laptop window still gets the shortcuts. */
.touch-help { display: none; }

@media (pointer: coarse) {
    .kb-help { display: none; }
    .touch-help { display: inline; }
}

kbd {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-bottom-width: 2px;
    border-radius: 5px;
    padding: 1px 5px;
    color: var(--ink);
}

.legend {
    margin-top: 0.8rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem 1rem;
    font-size: 0.78rem;
    color: var(--ink-dim);
    align-items: center;
}

.legend i {
    display: inline-block;
    width: 13px;
    height: 13px;
    border-radius: 4px;
    margin-right: 0.35rem;
    vertical-align: -2px;
}

.sw-grass { background: linear-gradient(#4fae54, #43a04a); }
.sw-sand { background: #e4d3a4; }
.sw-wood { background: repeating-linear-gradient(90deg, #a97c4c 0 4px, #8e6539 4px 6px); }
.sw-water { background: linear-gradient(#2f93c8, #14536f); }
.sw-gate { background: #e0a13a; }
.sw-blade { background: #d8523f; }

/* ── modals ─────────────────────────────────────────────────────────────── */

.modal {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(3, 10, 18, 0.74);
    backdrop-filter: blur(6px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s;
}

.modal.show { opacity: 1; pointer-events: auto; }

.modal-inner {
    width: min(480px, 100%);
    max-height: 88vh;
    overflow-y: auto;
    background: linear-gradient(160deg, rgba(20, 40, 58, 0.96), rgba(8, 20, 32, 0.96));
    border: 1px solid var(--panel-border);
    border-radius: 18px;
    padding: 1.4rem;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
    transform: translateY(10px) scale(0.98);
    transition: transform 0.22s;
}

.modal.show .modal-inner { transform: none; }

.modal h2 { margin: 0; font-size: 1.35rem; letter-spacing: -0.02em; }
.modal .sub { margin: 0.25rem 0 1rem; font-size: 0.82rem; color: var(--ink-dim); font-weight: 300; }

/* ── course picker ──────────────────────────────────────────────────────── */

.course-list {
    display: grid;
    gap: 0.6rem;
}

.course-card {
    display: grid;
    gap: 0.15rem;
    text-align: left;
    font: inherit;
    color: var(--ink);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--panel-border);
    border-radius: 14px;
    padding: 0.8rem 0.95rem;
    cursor: pointer;
    transition: background 0.18s, border-color 0.18s, transform 0.18s;
}

.course-card:hover {
    background: var(--accent-soft);
    border-color: rgba(125, 211, 252, 0.45);
    transform: translateY(-1px);
}

.cc-name { font-weight: 700; font-size: 1.02rem; }
.cc-blurb { font-size: 0.82rem; color: var(--ink-dim); font-weight: 300; }
.cc-meta {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--accent);
    margin-top: 0.2rem;
}

/* ── how to play ────────────────────────────────────────────────────────── */

.steps {
    margin: 0;
    padding-left: 1.3rem;
    display: grid;
    gap: 0.7rem;
    font-size: 0.87rem;
    font-weight: 300;
    line-height: 1.5;
    color: var(--ink-dim);
}

.steps li::marker { color: var(--accent); font-weight: 700; }
.steps b { color: var(--ink); font-weight: 600; }
.steps kbd { margin: 0 1px; }

.linkish {
    font: inherit;
    font-size: 0.82rem;
    color: var(--accent);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.linkish:hover { color: #7dd3fc; }

/* ── scorecard ──────────────────────────────────────────────────────────── */

.card-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
    font-variant-numeric: tabular-nums;
}

.card-table th {
    text-align: left;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-dim);
    font-weight: 600;
    padding-bottom: 0.4rem;
}

.card-table td { padding: 0.32rem 0; border-top: 1px solid rgba(255, 255, 255, 0.06); }
.card-table td.n { color: var(--ink-dim); width: 1.8rem; }
.card-table td.nm { font-weight: 500; }
.card-table th:last-child, .card-table td:last-child,
.card-table th:nth-child(3), .card-table td:nth-child(3) { text-align: right; width: 3rem; }

.card-table td.under { color: var(--under); font-weight: 700; }
.card-table td.over { color: var(--over); }
.card-table td.level { color: var(--accent); }
.card-table td.ace { color: var(--gold); font-weight: 800; }

.card-table tfoot td {
    border-top: 2px solid rgba(255, 255, 255, 0.16);
    font-weight: 700;
    padding-top: 0.5rem;
}

.modal-actions {
    display: flex;
    gap: 0.6rem;
    margin-top: 1.2rem;
}

.modal-actions button {
    flex: 1;
    font: inherit;
    font-weight: 600;
    border-radius: 12px;
    padding: 0.6rem;
    cursor: pointer;
    border: 1px solid var(--panel-border);
    background: rgba(255, 255, 255, 0.05);
    color: var(--ink);
    transition: background 0.18s, transform 0.18s;
}

.modal-actions button.primary {
    background: var(--accent);
    color: #06212f;
    border-color: transparent;
}

.modal-actions button:hover { background: var(--accent-soft); }
.modal-actions button.primary:hover { background: #7dd3fc; }
.modal-actions button:active { transform: translateY(1px); }

/* ── narrow screens ─────────────────────────────────────────────────────── */

@media (max-width: 760px) {
    .scoreboard {
        grid-template-columns: repeat(5, 1fr);
        row-gap: 0.7rem;
    }
    .scoreboard .stat:first-child { grid-column: 1 / -1; }
    .title { font-size: 1.25rem; }
    .tagline { display: none; }
    .topbar-actions { gap: 0.35rem; }
    button.chip { padding: 0.4rem 0.6rem; font-size: 0.78rem; }
    .hud-line { font-size: 0.72rem; gap: 0.45rem; }
}


/* ── immersive layout ───────────────────────────────────────────────────── */

/* On a phone — and on any window short or narrow enough that the clubhouse
   chrome would eat the course — the canvas takes the viewport and the
   scoreboard folds into the overlay it already has. Everything else stays
   where it was, one scroll below the fold. */
@media (max-width: 900px), (pointer: coarse) {
    body { padding: 0; }

    .wrap { max-width: none; }

    /* The course owns the screen; the help and the legend sit one scroll
       below it. */
    .viewport {
        display: flex;
        flex-direction: column;
        height: 100dvh;
    }

    .topbar {
        padding: 0.55rem 0.7rem;
        margin: 0;
        gap: 0.6rem;
    }

    .scoreboard { display: none; }

    .stage {
        flex: 1 1 auto;
        min-height: 55dvh;
        border-radius: 0;
        border-left: 0;
        border-right: 0;
        box-shadow: none;
    }

    canvas { height: 100%; }

    .stage-hud { display: block; }

    /* One row is not enough for the meter and the buttons on a phone, so they
       stack — both kept clear of the bag standing in the corner. */
    .controls {
        flex-direction: column;
        align-items: stretch;
        gap: 0.45rem;
        padding-left: min(34%, 150px);
        left: 10px;
        right: 10px;
        bottom: 10px;
    }

    .swing { flex: 1 1 auto; padding: 0.65rem 1rem; }

    .panel, .best-line { margin-left: 0.8rem; margin-right: 0.8rem; }
    .panel:last-of-type { margin-bottom: 2rem; }
}

@media (max-width: 900px) and (min-width: 641px), (pointer: coarse) and (min-width: 641px) {
    .stage-hud { top: 10px; left: 10px; }
}


/* ── the hole card ──────────────────────────────────────────────────────── */

/* What a hole is only needs saying once. It is said here, when the hole
   loads, and then it goes — rather than sitting under the name for the whole
   round taking up the width of the scoreboard. The name in the scoreboard and
   the overlay both ask for it back. */
.hole-card {
    position: absolute;
    left: 50%;
    top: 22%;
    transform: translate(-50%, 8px);
    width: min(34ch, calc(100% - 32px));
    padding: 0.85rem 1rem 0.9rem;
    text-align: center;
    line-height: 1.35;
    border-radius: 16px;
    background: rgba(5, 18, 28, 0.84);
    border: 1px solid var(--panel-border);
    backdrop-filter: blur(8px);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.35s ease, transform 0.35s ease;
    z-index: 4;
}

.hole-card.show { opacity: 1; transform: translate(-50%, 0); }

.hc-eyebrow {
    margin: 0;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--accent);
}

.hc-name {
    margin: 0.2rem 0 0;
    font-size: clamp(1.15rem, 4vw, 1.55rem);
    font-weight: 800;
    letter-spacing: -0.02em;
}

.hc-blurb {
    margin: 0.25rem 0 0;
    font-size: 0.84rem;
    font-weight: 300;
    color: var(--ink-dim);
}

.hc-meta {
    margin: 0.55rem 0 0;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--accent);
}

/* Two things at the top of the stage, and a phone with room for one: the offer
   of fullscreen gives way to whatever was asked for — the drawer, or the card
   naming the hole. */
.stage-hud.open ~ .fs-prompt,
.hole-card.show ~ .fs-prompt {
    opacity: 0;
    pointer-events: none;
}

/* Opening the bag dims the course; anything else floating over it would be
   read through four turning clubs. */
.stage.picker-open .stage-hud,
.stage.picker-open .fs-prompt,
.stage.picker-open .hole-card {
    opacity: 0;
    pointer-events: none;
}

/* ── compact chrome ─────────────────────────────────────────────────────── */

/* Set from game.js wherever the immersive layout is on — a phone, a coarse
   pointer, or fullscreen on anything. Two changes, and both are about giving
   the course back the pixels: the topbar stops standing above the canvas and
   starts floating over it, and five of the seven chips fold behind ☰. */
body.compact-ui .viewport { position: relative; }

body.compact-ui .topbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 6;
    margin: 0;
    padding: 0.45rem 0.6rem;
    gap: 0.5rem;
    background: linear-gradient(to bottom,
        rgba(4, 14, 24, 0.85) 0%, rgba(4, 14, 24, 0.5) 62%, rgba(4, 14, 24, 0) 100%);
    pointer-events: none;
}

/* The bar is a scrim, not a surface: only the things in it take a press, so
   a drag that starts on the sky above the course still turns the camera. */
body.compact-ui .topbar > * { pointer-events: auto; }

body.compact-ui .tagline { display: none; }
body.compact-ui .title { font-size: 1.05rem; white-space: nowrap; }

body.compact-ui .home-link {
    width: 32px;
    height: 32px;
    font-size: 1rem;
}

body.compact-ui .chip-menu { display: inline-block; }
body.compact-ui .chip-text { display: inline; }

body.compact-ui .topbar-menu {
    display: grid;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 8;
    gap: 0.35rem;
    min-width: 170px;
    padding: 0.4rem;
    background: rgba(9, 24, 38, 0.97);
    border: 1px solid var(--panel-border);
    border-radius: 14px;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55);
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s ease;
}

body.compact-ui .topbar-menu.open {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

body.compact-ui .topbar-menu .chip {
    text-align: left;
    background: rgba(255, 255, 255, 0.04);
}

/* Clear of the floating bar rather than under it. Everything that starts at
   the top of the stage starts below the bar instead — including the club
   picker's text, which is the one that used to run straight into it. */
body.compact-ui .stage-hud { top: 52px; left: 10px; }
body.compact-ui .fs-prompt { top: 52px; right: 10px; }
body.compact-ui .picker { padding-top: 52px; }

/* ── the panels below the fold ──────────────────────────────────────────── */

.panel {
    margin-top: 0.8rem;
    background: var(--panel);
    border: 1px solid var(--panel-border);
    border-radius: 14px;
    overflow: hidden;
}

.panel > summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    list-style: none;
    transition: background 0.15s;
}

.panel > summary::-webkit-details-marker { display: none; }

.panel > summary::before {
    content: '▸';
    color: var(--accent);
    font-size: 0.75rem;
    transition: transform 0.18s;
}

.panel[open] > summary::before { transform: rotate(90deg); }
.panel > summary:hover { background: var(--accent-soft); }

.panel .help,
.panel .legend {
    margin: 0;
    padding: 0 0.9rem 0.9rem;
}

.best-line {
    margin: 0.8rem 0 0;
    font-size: 0.8rem;
    color: var(--ink-dim);
}

.best-line b { color: var(--ink); }

/* ── short viewports ────────────────────────────────────────────────────── */

/* A phone held sideways has half the height and twice the need for it. */
@media (max-height: 520px) {
    body.compact-ui .topbar { padding: 0.3rem 0.5rem; }
    body.compact-ui .title { font-size: 0.95rem; }
    body.compact-ui .home-link { width: 28px; height: 28px; font-size: 0.9rem; }
    body.compact-ui .stage-hud { top: 44px; }
    body.compact-ui .fs-prompt { top: 44px; }
    body.compact-ui button.chip { padding: 0.3rem 0.55rem; font-size: 0.75rem; }

    .hole-card { top: 14%; padding: 0.6rem 0.9rem 0.65rem; }
    .hc-blurb { font-size: 0.78rem; }
    .hc-meta { margin-top: 0.35rem; }

    body.compact-ui .picker { padding-top: 44px; }
    .picker-title { display: none; }
    .picker-name { font-size: clamp(1.05rem, 3vw, 1.35rem); }
    .picker-blurb {
        margin-top: 0;
        max-width: 52ch;
        min-height: 1.35em;
        font-size: 0.75rem;
    }
    .picker-stats { margin-top: 0.15rem; font-size: 0.68rem; }
}

/* Shorter still and the wordmark is the first thing that can go: the back
   arrow already says where you are. */
@media (max-height: 420px) {
    body.compact-ui .brand { display: none; }
    body.compact-ui .stage-hud { top: 40px; }
    body.compact-ui .fs-prompt { top: 40px; }
    body.compact-ui .picker { padding-top: 40px; }
}
