/* ═══════════════════════════════════════════════════════════════
   CourtPoach / Thomson Park — site.css
   All tokens locked to DESIGN.md §3–§9. Canon wins every conflict.
   Red means YOU. Green means DO IT. Navy means the club.
   ═══════════════════════════════════════════════════════════════ */

:root {
    /* Surface */
    --tp-cream:       #FCF8ED;
    --tp-cream-high:  #F5EFDF;
    --tp-white:       #FFFFFF;

    /* Identity (canon) */
    --tp-navy:        #1F2C68;  /* matches the painted sign */
    --tp-red:         #C8282C;  /* sign lozenge red */
    --tp-green:       #CEE04A;  /* ball yellow-green */
    --tp-silver:      #B8BFC6;  /* recurring block bands */
    --tp-grey:        #8A8A80;  /* past / locked */
    --tp-grey-dim:    #6B6B62;  /* AA-contrast past-row text on cream-high */
    --tp-light-grey:  #D8D8D0;  /* subtle borders, read-only field chrome */

    /* Type */
    --tp-font-display: 'Big Shoulders Display', 'Arial Black', sans-serif;
    --tp-font-body:    'Public Sans', system-ui, sans-serif;

    /* Radii */
    --tp-r-chip:   12px;
    --tp-r-cell:   12px;
    --tp-r-button: 16px;
    --tp-r-modal:  20px;

    /* Shadow (modal cards only) */
    --tp-shadow-modal: 0 4px 8px rgba(31, 44, 104, 0.08);
}

/* ═══════════════════════════════════════
   Base
   ═══════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--tp-cream);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-size: 18px;
    line-height: 1.4;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

a {
    color: var(--tp-navy);
    text-decoration: none;
}

/* Inline links (inside running text) need a visual cue to be distinguishable from body copy.
   Standalone links — buttons, nav, back-links, grid cells — opt out via their own classes. */
p a,
li a {
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

button, input, select {
    font-family: inherit;
}

.visually-hidden {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Mobile-first, 60+ audience: make every checkbox easy to see and tap.
   flex-shrink: 0 so flex parents (e.g., a label with text) can't collapse the box
   down to its ~13px intrinsic width. */
    input[type="checkbox"] {
        width: 24px;
        height: 24px;
        flex-shrink: 0;
        accent-color: var(--tp-navy);
        cursor: pointer;
    }

/* ═══════════════════════════════════════
   Loader (overlay content) — tennis ball drop with squash + shadow.
   ═══════════════════════════════════════ */

.page-overlay {
    background: var(--tp-cream);
}

.tp-loader {
    position: relative;
    width: 56px;
    height: 96px;
    color: var(--tp-navy);
}

.tp-ball {
    position: absolute;
    left: 50%;
    top: 0;
    margin-left: -16px;
    width: 32px;
    height: 32px;
    transform-origin: 50% 100%;
    animation: tp-drop 1400ms cubic-bezier(.5,.05,.5,.95) infinite;
}

.tp-ball-rot {
    width: 100%;
    height: 100%;
    animation: tp-spin 1400ms cubic-bezier(.35,.1,.65,.9) infinite;
}

.tp-ball .tp-ball-svg {
    display: block;
    width: 100%;
    height: 100%;
}

.tp-loader-shadow {
    position: absolute;
    left: 50%;
    bottom: 5px;
    margin-left: -18px;
    width: 36px;
    height: 5px;
    border-radius: 50%;
    background: var(--tp-navy);
    opacity: 0.175;
    filter: blur(3px);
    animation: tp-drop-shadow 1400ms cubic-bezier(.5,.05,.5,.95) infinite;
}

@keyframes tp-drop {
    0%   { top: 0;    transform: scale(1, 1); }
    42%  { top: 52px; transform: scale(1, 1); }
    48%  { top: 56px; transform: scale(1.06, 0.92); }
    55%  { top: 55px; transform: scale(1.02, 0.97); }
    100% { top: 0;    transform: scale(1, 1); }
}

/* Rotation: most of the spin (300°) happens during descent (0–42%).
   Only ~15° during impact/squash; remaining ~45° drifts out through the slower ascent.
   Rate: ~7°/% falling vs ~1°/% rising — matches physical energy loss on bounce. */
@keyframes tp-spin {
    0%   { transform: rotate(0deg); }
    42%  { transform: rotate(300deg); }
    55%  { transform: rotate(315deg); }
    100% { transform: rotate(360deg); }
}

@keyframes tp-drop-shadow {
    0%        { transform: scale(0.35); opacity: 0.15; }
    42%, 55%  { transform: scale(1);    opacity: 0.4; }
    100%      { transform: scale(0.35); opacity: 0.15; }
}

/* ═══════════════════════════════════════
   Wordmark (DESIGN.md §7 — centered, racquets flanking)
   ═══════════════════════════════════════ */

.tp-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 16px;
    max-width: 640px;
    margin: 0 auto;
    width: 100%;
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--tp-cream);
}

.tp-wordmark {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--tp-navy);
    flex-shrink: 1;
    min-width: 0;
}

/* Admin site link — thin sticky footer. Only rendered for admins (ViewBag.IsAdmin).
   Navy bar pinned to bottom; page content reserves space via body padding-bottom. */
.tp-admin-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 25;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 16px calc(8px + env(safe-area-inset-bottom, 0px));
    background: var(--tp-navy);
    color: var(--tp-cream);
    font-family: var(--tp-font-body);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
}

.tp-admin-footer svg { display: block; }

body:has(.tp-admin-footer) { padding-bottom: 40px; }

/* Legal footer — small, unobtrusive privacy/terms links under the main content. Sits
   above the admin-footer bar on admin pages and above nothing on member pages. */
.tp-legal-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    padding: 24px 16px;
    font-family: var(--tp-font-body);
    font-size: 12px;
    color: #888;
    letter-spacing: 0.04em;
}
.tp-legal-footer a { color: inherit; text-decoration: none; }
.tp-legal-footer a:hover { color: var(--tp-navy); text-decoration: underline; }

/* Admin has its own fixed bottom bar; add bottom padding so the legal footer clears it. */
body:has(.tp-admin-footer) .tp-legal-footer { padding-bottom: 56px; }

/* Sysadmin impersonation banner — pinned to top, brightly coloured so nobody forgets.
   Higher z-index than the header and a larger top offset on the header (below) keep
   them from overlapping when both are sticky. */
.tp-impersonation-banner {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 16px;
    background: #b71c1c;
    color: #fff;
    font-family: var(--tp-font-body);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
}
body:has(.tp-impersonation-banner) .tp-header { top: 42px; }
body:has(.tp-impersonation-banner) .tp-admin-header { top: 42px; }
.tp-impersonation-banner button {
    background: #fff;
    color: #b71c1c;
    border: none;
    border-radius: 4px;
    padding: 4px 10px;
    font-weight: 700;
    font-size: 12px;
    cursor: pointer;
}

/* Long-form legal pages. */
.tp-legal {
    max-width: 720px;
    margin: 0 auto;
    padding: 16px 20px 48px;
    font-family: var(--tp-font-body);
    font-size: 15px;
    line-height: 1.55;
    color: var(--tp-navy);
}
.tp-legal h1 { margin: 24px 0 4px; }
.tp-legal h2 { font-size: 18px; font-weight: 700; margin: 28px 0 8px; }
.tp-legal ul { padding-left: 20px; margin: 8px 0 16px; }
.tp-legal .tp-muted { color: #999; font-size: 13px; margin-bottom: 24px; }

/* User chip — member name + upcoming-bookings badge, links to /Account. */
.tp-user-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    padding: 6px 10px 6px 12px;
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-chip);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
}

.tp-user-chip-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    opacity: 0.85;
}

.tp-user-chip-name {
    max-width: 96px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tp-user-chip-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 6px;
    background: var(--tp-red);
    color: var(--tp-cream);
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
}

.tp-wordmark-emblem {
    display: inline-block;
    margin-right: -6px;
    width: 40px;
    height: 40px;
    color: var(--tp-navy);
}

.tp-wordmark-emblem .tp-racquets {
    width: 100%;
    height: 100%;
}

.tp-wordmark-text {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    line-height: 0.95;
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 20px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.tp-wordmark-line {
    display: block;
}

@media (min-width: 420px) {
    .tp-wordmark-emblem { width: 48px; height: 48px; margin-right: -8px; }
    .tp-wordmark-text   { font-size: 24px; }
}

/* ═══════════════════════════════════════
   Main content
   ═══════════════════════════════════════ */

.tp-main {
    flex: 1;
    padding: 0 16px 32px;
    max-width: 640px;
    margin: 0 auto;
    width: 100%;
}

.tp-main:has(.tp-landing) { padding-bottom: 0; }

/* Pages that show the legal footer: don't stretch main to viewport height —
   let the footer sit naturally under the content instead of floating at the bottom. */
body:has(.tp-legal-footer) .tp-main { flex: 0 0 auto; }

/* ═══════════════════════════════════════
   Type utilities
   ═══════════════════════════════════════ */

.tp-display {
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 32px;
    line-height: 1.1;
    color: var(--tp-navy);
    margin: 0 0 12px;
    letter-spacing: 0.01em;
}

.tp-body {
    font-family: var(--tp-font-body);
    font-size: 20px;
    color: var(--tp-navy);
    margin: 0 0 16px;
}

/* ═══════════════════════════════════════
   Buttons (primary = green DO IT; destructive = red)
   ═══════════════════════════════════════ */

.tp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 56px;
    padding: 0 24px;
    border: 0;
    border-radius: var(--tp-r-button);
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 20px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    cursor: pointer;
    text-decoration: none;
}

.tp-btn-primary {
    background: var(--tp-green);
    color: var(--tp-navy);
}

.tp-btn-destructive {
    background: var(--tp-red);
    color: var(--tp-cream);
}

/* ═══════════════════════════════════════
   Full-screen state (success / error / limit / unknown)
   DESIGN.md §7 — unified composition
   ═══════════════════════════════════════ */

.tp-fullscreen-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    min-height: calc(100vh - 140px);
    text-align: center;
    padding: 32px 24px;
}

.tp-fullscreen-emblem {
    width: 96px;
    height: 96px;
    color: var(--tp-navy);
    margin-bottom: 8px;
}

.tp-fullscreen-emblem .tp-racquets { width: 100%; height: 100%; }

.tp-request-id {
    /* Dev-only debug breadcrumb; keeps at the hard floor so text-budget compliance holds. */
    font-family: var(--tp-font-body);
    font-size: 14px;
    color: var(--tp-grey);
    margin-top: 24px;
    letter-spacing: 0.02em;
}

/* ═══════════════════════════════════════
   Placeholder / landing bootstrap page
   ═══════════════════════════════════════ */

.tp-placeholder {
    padding: 48px 0;
    text-align: center;
}

/* ═══════════════════════════════════════
   Grid page — date chips, booking pill, 3-court grid
   DESIGN.md §7
   ═══════════════════════════════════════ */

.tp-grid-page {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Single sticky block that holds date chips, optional limit callout, and court
   column labels. One sticky container = no gap-covering hacks, no multi-element
   top syncing. JS sets `top` to the measured header height. */
.tp-sticky-top {
    position: sticky;
    top: 0; /* JS overrides to .tp-header.offsetHeight */
    z-index: 15;
    background: var(--tp-cream);
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding-bottom: 8px; /* breathing room before the scrolling grid */
}

/* --- Date chips (Today + configurable window) ---
   Horizontal scroll so long booking windows don't burn vertical space on mobile.
   Scroller pseudos (navy chevron + cream fade) appear when there's more content
   off-screen; JS toggles data-overflow-left/right on load/scroll/resize. */

.tp-date-chips-scroller {
    position: relative;
    padding: 8px 0 0;
}

.tp-date-chips {
    display: flex;
    flex-wrap: nowrap;
    justify-content: safe center;
    gap: 8px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
}

.tp-date-chips::-webkit-scrollbar { display: none; }

.tp-date-chips-scroller::before,
.tp-date-chips-scroller::after {
    content: "";
    position: absolute;
    top: 8px;
    bottom: 0;
    width: 36px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 150ms ease-out;
    background-repeat: no-repeat;
    background-size: 18px 18px, 100% 100%;
    z-index: 2;
}

.tp-date-chips-scroller::before {
    left: 0;
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231F2C68' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='15 6 9 12 15 18'/></svg>"),
        linear-gradient(to right, var(--tp-cream) 30%, transparent);
    background-position: left 4px center, left;
}

.tp-date-chips-scroller::after {
    right: 0;
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231F2C68' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='9 6 15 12 9 18'/></svg>"),
        linear-gradient(to left, var(--tp-cream) 30%, transparent);
    background-position: right 4px center, right;
}

.tp-date-chips-scroller[data-overflow-left]::before { opacity: 1; }
.tp-date-chips-scroller[data-overflow-right]::after { opacity: 1; }

.tp-date-chip {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex: 0 0 76px;
    scroll-snap-align: start;
    padding: 10px 8px;
    min-height: 64px;
    border: 2px solid var(--tp-navy);
    border-radius: var(--tp-r-chip);
    background: var(--tp-white);
    color: var(--tp-navy);
    text-decoration: none;
}

.tp-date-chip-label {
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.tp-date-chip-num {
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 22px;
    margin-top: 2px;
    line-height: 1;
}

.tp-date-chip--selected {
    background: var(--tp-navy);
    color: var(--tp-cream);
    border-color: var(--tp-navy);
}

.tp-date-chip--selected .tp-date-chip-label,
.tp-date-chip--selected .tp-date-chip-num {
    color: var(--tp-cream);
}

/* --- Booking-count pill --- */

.tp-pill {
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0 24px;
    border: 2px solid var(--tp-navy);
    border-radius: var(--tp-r-button);
    background: var(--tp-white);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-size: 18px;
    font-weight: 600;
    text-decoration: none;
}

.tp-pill--muted {
    opacity: 0.6;
}

/* Callout — informational FYI, not a button. No border/bg.
   Rendered inside .tp-sticky-top so it inherits the sticky behavior. */
.tp-callout {
    margin: 0;
    padding: 0 16px;
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-size: 18px;
    font-weight: 700;
    text-align: center;
}

.tp-callout-icon {
    display: inline-block;
    vertical-align: -4px;
    width: 20px;
    height: 20px;
    margin-right: 6px;
}

.tp-callout-link {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
}

/* Persistent booking-limit status line — always shown under the date chips
   when signed in. Neutral tone (no color shift at cap) because grid cells
   already grey out when a limit is reached. */
.tp-limit-status {
    margin: 0;
    padding: 4px 16px 0;
    display: flex;
    justify-content: center;
    gap: 10px;
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-size: 14px;
    font-weight: 500;
}

.tp-limit-status strong { font-weight: 700; }

.tp-limit-sep { color: var(--tp-grey); }

.tp-limit-item {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.tp-limit-hazard {
    width: 16px;
    height: 16px;
    fill: var(--tp-red);
}

/* Toast-style alerts (override for the Common RCL Alert component). */
.tp-alerts {
    position: fixed;
    top: 12px;
    right: 12px;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

.tp-alert {
    padding: 10px 16px;
    border-radius: var(--tp-r-button);
    background: var(--tp-navy);
    color: var(--tp-cream);
    font-family: var(--tp-font-body);
    font-size: 14px;
    font-weight: 600;
    box-shadow: var(--tp-shadow-modal);
    opacity: 1;
    transition: opacity 300ms ease-out;
    max-width: 320px;
}

.tp-alert--danger { background: var(--tp-red); }
.tp-alert--success { background: var(--tp-navy); }
.tp-alert--fade { opacity: 0; }

/* --- Grid --- */

.tp-grid {
    display: grid;
    grid-template-columns: 52px repeat(3, 1fr);
    grid-template-rows: auto;
    grid-auto-rows: minmax(64px, auto);
    column-gap: 8px;
    row-gap: 8px;
}

/* Court-column labels row — lives inside .tp-grid as its first row so ARIA
   hierarchy (role="table" > role="row" > role="columnheader") is satisfied.
   display: contents hoists children into the parent grid so columns auto-align. */
.tp-grid > .tp-grid-head {
    display: contents;
}

/* Cell wrapper owns role="cell" and grid placement so anchors/spans keep their
   native role for axe (aria-allowed-role). Inner element fills the wrapper so
   the tap target stays the whole cell. */
.tp-grid [role="cell"] {
    display: flex;
}
.tp-grid [role="cell"] > .tp-cell,
.tp-grid [role="cell"] > .tp-band {
    width: 100%;
    min-height: 64px;
}

.tp-col-court {
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--tp-navy);
    text-align: center;
    padding: 4px 0;
}

.tp-grid-row {
    display: contents;
}

.tp-col-time {
    font-family: var(--tp-font-body);
    font-weight: 600;
    font-size: 14px;
    color: var(--tp-navy);
    text-align: right;
    padding-right: 4px;
    align-self: center;
}

.tp-grid-row--past .tp-col-time {
    color: var(--tp-grey-dim);
}

/* Past rows stay visible so earlier bookings aren't "lost" on today's grid,
   but cells are non-interactive. Only --mine needs dimming — the other states
   are already visually subdued in their base form, so double-dimming hurts
   legibility without adding "past-ness". */
.tp-grid-row--past .tp-cell {
    pointer-events: none;
    cursor: default;
}
.tp-grid-row--past .tp-cell--mine {
    opacity: 0.5;
}

/* --- Cells (DESIGN.md §7 cell states) --- */

.tp-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 64px;
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-cell);
    background: var(--tp-white);
    color: var(--tp-navy);
    position: relative;
    text-decoration: none;
    font-family: var(--tp-font-body);
    font-size: 16px;
    font-weight: 500;
}

.tp-cell--free .tp-ball-svg {
    width: 28px;
    height: 28px;
}

.tp-cell--mine {
    background: var(--tp-red);
    border-color: var(--tp-red);
    color: var(--tp-cream);
}

.tp-check {
    width: 32px;
    height: 32px;
}

/* Unbookable cells — past hours and slots booked by another member.
   Same "grey disabled" treatment; "other" keeps navy name for readability. */
.tp-cell--past,
.tp-cell--other {
    background: var(--tp-cream-high);
    border-color: var(--tp-grey);
    cursor: default;
}

.tp-cell--past  { color: var(--tp-grey); }
.tp-cell--other { color: var(--tp-navy); }

.tp-cell--mine .tp-cell-name {
    padding: 0 6px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
    font-weight: 700;
}

.tp-cell--other .tp-cell-name {
    padding: 0 6px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.tp-cell--blocked,
.tp-band {
    background: var(--tp-silver);
    border-color: var(--tp-silver);
    color: var(--tp-navy);
}

.tp-cell--blocked .tp-cell-block-label {
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.01em;
    text-align: center;
    padding: 0 4px;
    line-height: 1.05;
    word-break: break-word;
    hyphens: auto;
    max-width: 100%;
    overflow: hidden;
}

/* Club-event block — covers a rectangle of one or more courts × one or more hours.
   Grid placement (start column/row + spans) is applied inline per instance by the view. */

.tp-band {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 64px;
    border-radius: var(--tp-r-cell);
    border-width: 1px;
    border-style: solid;
    /* Match the per-cell blocked label so bands and single-court blocks read as
       the same class (body font, bold all-caps). Slightly larger + more tracking
       than the cell variant since the band has horizontal room to breathe. */
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 15px;
    letter-spacing: 0.04em;
}

.tp-band-label {
    padding: 0 12px;
    text-align: center;
}

/* ═══════════════════════════════════════
   Landing page — pitch surface for prospective club leaders.
   Audience: club presidents and volunteer board members, often
   first/second-gen immigrants. Plain language; ease-of-use focused.
   No member-finder logic — members enter via per-club invite links.
   ═══════════════════════════════════════ */

.tp-landing {
    padding: 0;
}

.tp-landing-hero {
    text-align: center;
    padding: 72px 24px 64px;
    background: var(--tp-cream-high);
    clip-path: inset(0 -100vmax);
    box-shadow: 0 0 0 100vmax var(--tp-cream-high);
}

.tp-landing-hero + .tp-landing-section { padding-top: 64px; }
.tp-landing-section:has(+ .tp-landing-cta-block) { padding-bottom: 64px; }
.tp-landing-section:not(.tp-landing-stripe):has(+ .tp-landing-stripe) { padding-bottom: 64px; }
.tp-landing-stripe + .tp-landing-section:not(.tp-landing-stripe) { padding-top: 64px; }

.tp-landing-pitch {
    font-size: 48px;
    line-height: 1;
    margin: 0 0 40px;
    letter-spacing: 0.01em;
}

@media (min-width: 480px) {
    .tp-landing-pitch { font-size: 80px; }
}

@media (min-width: 768px) {
    .tp-landing-pitch { font-size: 104px; }
}

.tp-landing-wordmark {
    display: inline-flex;
    align-items: center;
    gap: 0;
    margin-bottom: 12px;
}

.tp-landing-wordmark-emblem {
    display: inline-block;
    width: 28px;
    height: 28px;
    color: var(--tp-navy);
    margin-right: -4px;
}

.tp-landing-wordmark-emblem .tp-racquets { width: 100%; height: 100%; }

.tp-landing-wordmark-text {
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 18px;
    color: var(--tp-navy);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    line-height: 1;
}

.tp-landing-microcopy {
    font-family: var(--tp-font-body);
    font-size: 14px;
    color: var(--tp-navy);
    opacity: 0.7;
    margin: 12px 0 0;
}

.tp-landing-section {
    padding: 32px 0;
}

.tp-landing-stripe {
    background: #fff;
    clip-path: inset(0 -100vmax);
    box-shadow: 0 0 0 100vmax #fff;
    padding-top: 56px;
    padding-bottom: 56px;
}

.tp-landing-stripe + .tp-landing-stripe { padding-top: 12px; }
.tp-landing-stripe:has(+ .tp-landing-stripe) { padding-bottom: 12px; }

.tp-landing-section-title {
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 28px;
    color: var(--tp-navy);
    margin: 0 0 16px;
    letter-spacing: 0.01em;
}

.tp-landing-section p {
    font-family: var(--tp-font-body);
    font-size: 18px;
    color: var(--tp-navy);
    margin: 0 0 12px;
    line-height: 1.5;
}

.tp-landing-section p:last-child { margin-bottom: 0; }

.tp-landing-checklist {
    list-style: none;
    padding: 0;
    margin: 0 0 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.tp-landing-checklist:last-child { margin-bottom: 0; }

.tp-landing-checklist li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    font-family: var(--tp-font-body);
    font-size: 18px;
    color: var(--tp-navy);
    line-height: 1.4;
}

.tp-landing-check {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    margin-top: 1px;
    color: var(--tp-navy);
}

.tp-landing-manifesto {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.tp-landing-manifesto-pane {
    border: 0;
    border-radius: 0;
    padding: 0;
    background: transparent;
    display: flex;
    flex-direction: column;
}

.tp-landing-manifesto-pane + .tp-landing-manifesto-pane {
    margin-top: 32px;
}

.tp-landing-manifesto-title {
    font-family: var(--tp-font-body);
    font-weight: 200;
    font-size: 24px;
    margin: 0 0 14px;
    letter-spacing: 0.01em;
    color: var(--tp-navy);
}

.tp-landing-manifesto-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.tp-landing-manifesto-list li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-family: var(--tp-font-body);
    font-size: 17px;
    line-height: 1.4;
    color: inherit;
}

.tp-landing-manifesto-list li span { flex: 1; }

.tp-landing-manifesto-isnt .tp-landing-manifesto-list li { color: rgba(31, 44, 104, 0.7); }

.tp-landing-cross,
.tp-landing-arrow {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    margin-top: 1px;
}

.tp-landing-cross { color: rgba(31, 44, 104, 0.45); }
.tp-landing-arrow { color: var(--tp-navy); }

.tp-landing-cta-block {
    text-align: center;
    padding: 64px 24px 72px;
    background: var(--tp-cream-high);
    clip-path: inset(0 -100vmax);
    box-shadow: 0 0 0 100vmax var(--tp-cream-high);
}

.tp-landing-cta-block .tp-landing-section-title {
    margin-bottom: 12px;
}

.tp-landing-cta-block p {
    font-family: var(--tp-font-body);
    font-size: 18px;
    color: var(--tp-navy);
    margin: 0 auto 24px;
    max-width: 480px;
    line-height: 1.5;
}

.tp-landing-cta-block .tp-btn {
    width: 100%;
    max-width: 360px;
}

.tp-landing-faq {
    display: flex;
    flex-direction: column;
}

.tp-landing-faq-item {
    border-top: 1px solid var(--tp-light-grey);
}

.tp-landing-faq-item:last-child {
    border-bottom: 1px solid var(--tp-light-grey);
}

.tp-landing-faq-summary {
    cursor: pointer;
    padding: 16px 0;
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 20px;
    color: var(--tp-navy);
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    letter-spacing: 0.01em;
}

.tp-landing-faq-summary::-webkit-details-marker { display: none; }

.tp-landing-faq-summary::after {
    content: "+";
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 26px;
    color: var(--tp-navy);
    flex-shrink: 0;
    line-height: 1;
}

.tp-landing-faq-item[open] .tp-landing-faq-summary::after {
    content: "−";
}

.tp-landing-faq-item p {
    font-family: var(--tp-font-body);
    font-size: 18px;
    color: var(--tp-navy);
    margin: 0 0 16px;
    line-height: 1.5;
}

.tp-landing-footer {
    text-align: center;
    padding: 32px 16px 16px;
    margin-top: 16px;
    font-family: var(--tp-font-body);
    font-size: 14px;
    color: var(--tp-navy);
    opacity: 0.6;
    border-top: 1px solid var(--tp-light-grey);
}

.tp-landing-section .tp-landing-price {
    font-family: var(--tp-font-body);
    font-weight: 200;
    font-size: 24px;
    line-height: 1.4;
    color: var(--tp-navy);
    letter-spacing: 0.01em;
    margin: 24px 0 32px;
}

/* ═══════════════════════════════════════
   Dev sign-in panel (Development only)
   ═══════════════════════════════════════ */
.tp-dev-panel {
    max-width: 480px;
    margin: 48px auto;
    padding: 24px;
    background: var(--tp-cream);
    border: 2px solid var(--tp-navy);
    border-radius: var(--tp-r-modal);
}

.tp-dev-list {
    list-style: none;
    padding: 0;
    margin: 16px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.tp-dev-list .tp-btn { width: 100%; }

.tp-dev-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px 12px;
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-chip);
    background: var(--tp-white);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
}

.tp-dev-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-chip);
    overflow: hidden;
    margin-top: 8px;
}

.tp-dev-table th,
.tp-dev-table td {
    padding: 8px 10px;
    text-align: left;
    border-bottom: 1px solid var(--tp-cream-high);
    font-size: 14px;
}

.tp-dev-table th {
    background: var(--tp-cream-high);
    font-weight: 700;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tp-navy);
}

.tp-dev-table tbody tr:last-child td { border-bottom: 0; }

/* ═══════════════════════════════════════
   Full-page booking detail (confirm / success / cancel / state pages)
   DESIGN.md §7 — unified composition
   ═══════════════════════════════════════ */

.tp-full-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(100vh - 120px);
    padding: 24px 0;
}

.tp-booking-detail {
    width: 100%;
    max-width: 420px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    text-align: center;
}

.tp-booking-emblem {
    width: 72px;
    height: 72px;
    color: var(--tp-navy);
}

.tp-booking-emblem .tp-racquets { width: 100%; height: 100%; }

/* Spinning tennis ball on the booking Confirm/Cancel/Success screens — avoids
   repeating the crossed-racquets emblem that already sits in the top-left
   wordmark. The inner SVG spins so the ground-shadow pseudo-element (::after)
   can stay still underneath, giving the "rolling along the ground" read. */
.tp-booking-ball {
    width: 72px;
    height: 72px;
    position: relative;
}

.tp-booking-ball .tp-ball-svg {
    width: 100%;
    height: 100%;
    display: block;
    animation: tp-spin-steady 2400ms linear infinite;
}

/* ::before so the shadow paints underneath the SVG in DOM paint order —
   the opaque green circle occludes any shadow that would otherwise bleed
   through the ball's transparent viewBox corners. */
.tp-booking-ball::before {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 2px;
    /* Mirror of the previous right-tailing shadow: element is now anchored
       mostly to the left of center, dark core tucked under the ball on its
       right side, tail fading out to the left — reads as a light source
       from the upper-right (ball rolling toward the sun). */
    transform: translateX(-90%);
    width: 114%;
    height: 8.5px;
    border-radius: 50%;
    background: radial-gradient(ellipse at 75% 50%,
        rgba(31, 44, 104, 0.2) 0%,
        rgba(31, 44, 104, 0.1) 45%,
        rgba(31, 44, 104, 0) 85%);
    filter: blur(2.5px);
    pointer-events: none;
}

@keyframes tp-spin-steady {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.tp-booking-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    line-height: 1.05;
}

.tp-booking-stack--inline {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: center;
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 22px;
}

.tp-booking-day,
.tp-booking-time,
.tp-booking-court {
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 40px;
    color: var(--tp-navy);
}

.tp-booking-stack--inline .tp-booking-day,
.tp-booking-stack--inline .tp-booking-time,
.tp-booking-stack--inline .tp-booking-court {
    font-size: 22px;
}

.tp-booking-dot { color: var(--tp-navy); font-size: 22px; }

.tp-booking-meta {
    margin: 0;
    color: var(--tp-navy);
    font-size: 18px;
}

.tp-booking-actions {
    width: 100%;
    margin-top: 8px;
}

.tp-btn-full { width: 100%; }

.tp-btn-locked {
    background: var(--tp-grey);
    color: var(--tp-cream);
    cursor: not-allowed;
    pointer-events: none;
}

.tp-back-link,
.tp-signout-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--tp-navy);
    font-size: 16px;
    text-decoration: underline;
    padding: 8px 0;
}

button.tp-signout-link {
    background: none;
    border: 0;
    font-family: inherit;
    cursor: pointer;
}

.tp-back-link::before,
.tp-signout-link::before {
    content: "";
    display: inline-block;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

.tp-back-link::before {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231F2C68' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='15 18 9 12 15 6'/></svg>");
}

.tp-signout-link::before {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231F2C68' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/><polyline points='16 17 21 12 16 7'/><line x1='21' y1='12' x2='9' y2='12'/></svg>");
}

.tp-footer-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
}

.tp-display-hero {
    font-size: 40px;
    margin: 0;
}

.tp-hero-check {
    width: 140px;
    height: 140px;
}

.tp-hero-check svg { width: 100%; height: 100%; }

/* ═══════════════════════════════════════
   My bookings list
   ═══════════════════════════════════════ */

.tp-mybookings {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 16px 0;
}

.tp-booking-card-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.tp-booking-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: transparent;
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-modal);
    padding: 12px 16px;
}

.tp-booking-card-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.tp-booking-card-day {
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 22px;
    color: var(--tp-navy);
}

.tp-booking-card-time {
    font-family: var(--tp-font-body);
    font-size: 18px;
    color: var(--tp-navy);
}

.tp-booking-card-x {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 0 12px;
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-button);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
}

.tp-booking-card-x svg { width: 20px; height: 20px; }

/* ═══════════════════════════════════════
   Account page — profile card + display-name editor
   ═══════════════════════════════════════ */

.tp-account {
    display: flex;
    flex-direction: column;
    gap: 24px;
    padding: 16px 0;
}

.tp-account-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.tp-display--h2 {
    font-size: 24px;
}

.tp-account-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-modal);
    padding: 12px 16px;
}

.tp-account-row-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.tp-account-row-label {
    font-family: var(--tp-font-body);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tp-navy);
    opacity: 0.7;
}

.tp-account-row-value {
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 22px;
    color: var(--tp-navy);
}

.tp-account-edit {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 14px;
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-button);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
}

.tp-account-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.tp-account-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.tp-account-label {
    font-family: var(--tp-font-body);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tp-navy);
}

.tp-account-input {
    min-height: 44px;
    padding: 8px 12px;
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-button);
    color: var(--tp-navy);
    font-family: var(--tp-font-body);
    font-size: 18px;
}

.tp-account-hint {
    font-family: var(--tp-font-body);
    font-size: 14px;
    color: var(--tp-navy);
    opacity: 0.7;
    margin: 0;
}

.tp-account-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

.tp-account-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 18px;
    border-radius: var(--tp-r-button);
    font-family: var(--tp-font-body);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

.tp-account-btn--primary {
    background: var(--tp-navy);
    border: 1px solid var(--tp-navy);
    color: var(--tp-white);
}

.tp-account-btn--ghost {
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    color: var(--tp-navy);
}

/* ═══════════════════════════════════════
   Welcome overlay (one-time after consent)
   ═══════════════════════════════════════ */

.tp-welcome-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(31, 44, 104, 0.55);
    overflow-y: auto;
}

.tp-welcome-card {
    width: 100%;
    max-width: 440px;
    background: var(--tp-cream);
    border: 2px solid var(--tp-navy);
    border-radius: var(--tp-r-modal);
    padding: 28px 24px;
    box-shadow: var(--tp-shadow-modal);
}

.tp-welcome-title {
    margin: 0 0 16px;
    font-family: var(--tp-font-display);
    font-weight: 900;
    font-size: 36px;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--tp-navy);
}

.tp-welcome-body {
    margin: 0 0 8px;
    font-size: 17px;
    line-height: 1.4;
    color: var(--tp-navy);
}

.tp-welcome-url {
    margin: 0 0 20px;
    padding: 12px 14px;
    background: var(--tp-white);
    border: 1px solid var(--tp-navy);
    border-radius: var(--tp-r-chip);
    font-weight: 700;
    font-size: 17px;
    color: var(--tp-navy);
    word-break: break-all;
}

.tp-welcome-hints {
    margin: 16px 0 24px;
    padding: 0 0 0 2px;
    list-style: none;
}

.tp-welcome-hints li {
    padding: 6px 0;
    font-size: 16px;
    line-height: 1.4;
    color: var(--tp-navy);
}

.tp-welcome-btn {
    width: 100%;
    height: 48px;
    font-size: 16px;
}

/* ═══════════════════════════════════════
   Motion — DESIGN.md §8
   Every animation must respect prefers-reduced-motion.
   ═══════════════════════════════════════ */

/* Date chip press: scale to 96% then spring back via transition */
.tp-date-chip {
    transition: transform 120ms cubic-bezier(0.2, 1, 0.3, 1);
}
.tp-date-chip:active {
    transform: scale(0.96);
}

/* Cell tap (bookable Free cell): scale to 102% briefly */
.tp-cell--free {
    transition: transform 120ms ease-out;
}
.tp-cell--free:active {
    transform: scale(1.02);
}

/* Mine cell press gives tactile feedback before cancel page loads */
.tp-cell--mine:active {
    transform: scale(0.98);
    transition: transform 120ms ease-out;
}

/* Buttons: subtle press */
.tp-btn {
    transition: transform 120ms ease-out, background 120ms ease-out;
}
.tp-btn:active:not(.tp-btn-locked) {
    transform: scale(0.98);
}

/* Success: stroke-by-stroke checkmark draw */
.tp-hero-check svg circle {
    transform-origin: 60px 60px;
    animation: tp-pop 260ms cubic-bezier(0.2, 1, 0.3, 1) both;
}
.tp-hero-check svg path {
    stroke-dasharray: 90;
    stroke-dashoffset: 90;
    animation: tp-draw 250ms 200ms ease-out both;
}

@keyframes tp-pop {
    0%   { transform: scale(0.6); opacity: 0; }
    100% { transform: scale(1);    opacity: 1; }
}
@keyframes tp-draw {
    to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .tp-date-chip,
    .tp-cell--free,
    .tp-cell--mine,
    .tp-btn {
        transition: none;
    }
    .tp-date-chip:active,
    .tp-cell--free:active,
    .tp-cell--mine:active,
    .tp-btn:active:not(.tp-btn-locked) {
        transform: none;
    }
    .tp-hero-check svg circle,
    .tp-hero-check svg path,
    .tp-ball,
    .tp-ball-rot,
    .tp-loader-shadow,
    .tp-booking-ball .tp-ball-svg {
        animation: none;
    }
    .tp-hero-check svg path {
        stroke-dashoffset: 0;
    }
}
