/* One plain CSS file: no build step, no framework, no JS dependency.
   Tokens first, then components, each one class.

   Read it as: what things are made of -> what things are -> where they sit. */

/* ---------------------------------------------------------------- tokens */

:root {
    /* Lets the browser paint its own widgets — fields, scrollbars, the date
       picker — in the right theme instead of leaving them white. */
    color-scheme: light dark;

    --ground: #f5f6f4;
    --surface: #ffffff;
    --surface-sunk: #eef0ed;
    --ink: #161a17;
    --ink-soft: #5a625b;
    --line: #dee2dd;

    /* Padel is played on a court, so the accent is one. */
    --accent: #1f7a4d;
    --accent-ink: #ffffff;
    --accent-wash: #e3f1e9;

    /* Seat counts. Never the only carrier of the meaning — the text still
       says "2 / 4" — but colour makes a full game skippable at a glance. */
    --free: #1f7a4d;
    --free-wash: #e3f1e9;
    --last: #8a5a00;
    --last-wash: #fbf0da;
    --full: #5a625b;
    --full-wash: #e9ebe8;

    --danger: #b3261e;
    --danger-wash: #fbe6e4;

    --radius: 12px;
    --radius-lg: 16px;
    --radius-pill: 999px;

    --gap-xs: .35rem;
    --gap-sm: .6rem;
    --gap: 1rem;
    --gap-lg: 1.5rem;

    --shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 8px 20px rgb(0 0 0 / 4%);

    /* How much room the fixed bottom bar needs. One number, used by the bar
       itself, by the body padding and by anything that sits above it. */
    --bar: 4rem;
}

@media (prefers-color-scheme: dark) {
    :root {
        --ground: #101311;
        --surface: #191d1a;
        --surface-sunk: #141715;
        --ink: #e8ece8;
        --ink-soft: #a0a8a1;
        --line: #2a302c;

        --accent: #4cc38a;
        --accent-ink: #06231a;
        --accent-wash: #163024;

        --free: #4cc38a;
        --free-wash: #163024;
        --last: #e0a33a;
        --last-wash: #33270f;
        --full: #a0a8a1;
        --full-wash: #232724;

        --danger: #f2726a;
        --danger-wash: #331b19;

        --shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 8px 20px rgb(0 0 0 / 25%);
    }
}

/* ------------------------------------------------------- inside Telegram */

/* The same pages, opened as a Mini App.

   Telegram hands the page its client's palette in --tg-theme-*, and that
   palette is not the phone's: a dark Telegram on a light phone is an ordinary
   thing to have. So prefers-color-scheme is the wrong question in here, which
   is why this block sits after the media query rather than inside one, and why
   the few colours Telegram does not name are picked with light-dark() — the
   root's color-scheme is set from Telegram's own answer in base.html.twig.

   Only the colours Telegram actually names are taken from it. A wash has no
   counterpart there, so each one is mixed: a wash is one of our colours
   dissolved in the surface it sits on, and that holds in either theme. */
.tma {
    --ground: var(--tg-theme-secondary-bg-color, light-dark(#f5f6f4, #101311));
    --surface: var(--tg-theme-bg-color, light-dark(#ffffff, #191d1a));
    --surface-sunk: var(--tg-theme-secondary-bg-color, light-dark(#eef0ed, #141715));
    --ink: var(--tg-theme-text-color, light-dark(#161a17, #e8ece8));
    --ink-soft: var(--tg-theme-hint-color, light-dark(#5a625b, #a0a8a1));
    --line: var(--tg-theme-section-separator-color, light-dark(#dee2dd, #2a302c));

    /* The court green gives way to whatever the client's buttons are: inside
       Telegram the accent is the one thing on the screen that is already
       answered, and two accents would read as two applications. */
    --accent: var(--tg-theme-button-color, light-dark(#1f7a4d, #4cc38a));
    --accent-ink: var(--tg-theme-button-text-color, light-dark(#ffffff, #06231a));
    --accent-wash: color-mix(in srgb, var(--accent) 14%, var(--surface));

    /* Free seats are the accent, because a free seat is the thing to tap. */
    --free: var(--accent);
    --free-wash: var(--accent-wash);
    --last: light-dark(#8a5a00, #e0a33a);
    --last-wash: color-mix(in srgb, var(--last) 16%, var(--surface));
    --full: var(--ink-soft);
    --full-wash: color-mix(in srgb, var(--full) 14%, var(--surface));

    --danger: var(--tg-theme-destructive-text-color, light-dark(#b3261e, #f2726a));
    --danger-wash: color-mix(in srgb, var(--danger) 12%, var(--surface));

    /* light-dark() takes two colours and nothing else, so the switch is inside
       the shadow rather than around it. */
    --shadow:
        0 1px 2px light-dark(rgb(0 0 0 / 6%), rgb(0 0 0 / 40%)),
        0 8px 20px light-dark(rgb(0 0 0 / 4%), rgb(0 0 0 / 25%));
}

/* ---------------------------------------------------------------- basics */

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--ground);
    color: var(--ink);
    font: 16px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
    -webkit-text-size-adjust: 100%;

    /* The strip iOS keeps for the home indicator. */
    padding-bottom: env(safe-area-inset-bottom);
}

/* Room for the fixed bar, but only on the pages that have one — the sign-in
   and sign-up pages carry no navigation. */
body.has-nav { padding-bottom: calc(var(--bar) + env(safe-area-inset-bottom)); }

/* Anything under 16px makes Safari zoom the page the moment a field takes
   focus, and a finger is 44px wide, not 24. Both apply to every control, so
   both are stated once, here. */
input, select, textarea, button { font-size: 16px; font-family: inherit; }
input, select, .btn { min-height: 44px; }

a { color: var(--accent); }

h1 { font-size: 1.5rem; line-height: 1.2; letter-spacing: -.01em; margin: 0 0 var(--gap-xs); }
h2 { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft); margin: 0 0 var(--gap-sm); }

.lede { color: var(--ink-soft); margin: 0 0 var(--gap-lg); }

/* On a phone this is the whole width; on a desktop it is a column somebody can
   read, rather than a line stretched across 27 inches. */
.wrap {
    max-width: 34rem;
    margin: 0 auto;
    padding: var(--gap) var(--gap) var(--gap-lg);
}

/* ---------------------------------------------------------------- header */

.head {
    display: flex; align-items: center; gap: var(--gap);
    padding: var(--gap-sm) var(--gap);
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.brand {
    font-weight: 650; letter-spacing: -.01em;
    color: inherit; text-decoration: none;
}

.head__who { margin-left: auto; color: var(--ink-soft); font-size: .875rem; }

/* ------------------------------------------------------------ navigation */

/* Pinned to the bottom, because a thumb reaches the bottom of a phone and does
   not reach the top. It moves into the header once the screen is wide enough
   for that to be the natural place instead. */
.nav {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 10;
    display: flex;
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom);
}

.nav__item {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px;
    min-height: var(--bar);
    padding: .3rem .2rem;
    color: var(--ink-soft);
    font-size: .7rem;
    text-decoration: none;
}

.nav__item--active { color: var(--accent); font-weight: 600; }

.nav__glyph { position: relative; font-size: 1.15rem; line-height: 1; }

/* Creating a game is the point of the app, so it is the one item that looks
   like a button. */
.nav__item--add .nav__glyph {
    display: grid; place-items: center;
    width: 2.1rem; height: 2.1rem;
    border-radius: var(--radius-pill);
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 1.35rem;
}

/* Nothing notifies anybody, so this number is the only hint that something
   moved in "Mine" — a promotion out of a queue, most of all. */
.nav__count {
    position: absolute; top: -.5rem; left: .7rem;
    min-width: 1.05rem; padding: 0 .25rem;
    border-radius: var(--radius-pill);
    background: var(--accent); color: var(--accent-ink);
    font-size: .65rem; line-height: 1.05rem; text-align: center;
    font-variant-numeric: tabular-nums; font-weight: 700;
}

@media (min-width: 40rem) {
    body.has-nav { padding-bottom: env(safe-area-inset-bottom); }

    .nav {
        position: static;
        border-top: 0;
        padding-bottom: 0;
        gap: .25rem;
    }

    .nav__item {
        flex: 0 0 auto;
        flex-direction: row;
        gap: .35rem;
        min-height: 2.25rem;
        padding: .25rem .55rem;
        font-size: .875rem;
        border-radius: var(--radius);
    }

    .nav__item--active { background: var(--accent-wash); }

    .nav__glyph { font-size: 1rem; }
    .nav__item--add .nav__glyph { width: 1.5rem; height: 1.5rem; font-size: 1rem; }
    .nav__count { position: static; }
}

/* --------------------------------------------------------------- flashes */

/* Above the content and hard to skim past. Colour is not the only difference:
   each one carries a mark, so they still read apart in greyscale and out
   loud, and two in a row read as two messages rather than one paragraph. */
.flash {
    display: flex; gap: var(--gap-sm); align-items: flex-start;
    margin: 0 0 var(--gap-sm);
    padding: .75rem .85rem;
    border: 1px solid;
    border-radius: var(--radius);
}

.flash__mark { font-weight: 700; line-height: 1.5; }

.flash--success { background: var(--free-wash); border-color: var(--free); color: var(--ink); }
.flash--success .flash__mark { color: var(--free); }

.flash--error { background: var(--danger-wash); border-color: var(--danger); color: var(--ink); }
.flash--error .flash__mark { color: var(--danger); }

/* --------------------------------------------------------------- buttons */

.btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: .4rem;
    padding: .55rem 1.1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    text-decoration: none;
    cursor: pointer;
}

.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.btn--outline { background: transparent; border-color: var(--accent); color: var(--accent); font-weight: 600; }
.btn--quiet { background: transparent; color: var(--ink-soft); }
.btn--danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn--block { display: flex; width: 100%; }
/* Telegram's own blue, not the app's accent: this button leaves for another
   application, and it is the one place that is worth saying in colour. */
.btn--telegram { background: #229ed9; border-color: #229ed9; color: #fff; font-weight: 600; }
.btn--small { min-height: 36px; padding: .3rem .75rem; font-size: .8rem; }

.btn[disabled] { opacity: .5; cursor: not-allowed; }

.btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ----------------------------------------------------------------- forms */

.field {
    display: flex; flex-direction: column; gap: var(--gap-xs);
    margin: 0 0 var(--gap);
    /* Also used on <fieldset>, whose default border, padding and minimum width
       would otherwise draw a box around one group and not the others. */
    border: 0; padding: 0; min-inline-size: 0;
}

/* A class selector outranks the browser's own [hidden] { display: none }, so
   without this the field stays on screen when a script hides it. */
.field[hidden] { display: none; }

.field__label { padding: 0; font-size: .875rem; color: var(--ink-soft); }
.field__row { display: flex; flex-wrap: wrap; gap: var(--gap-xs); align-items: center; }
.field__row input { flex: 1 1 8rem; }

.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="date"],
.field input[type="time"],
.field select {
    width: 100%;
    padding: .55rem .7rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: inherit;
}

/* A row of tap targets instead of a dropdown: picking "1 h 30 min" is one tap
   here and three interactions in a <select>. */
.choice { display: flex; flex-wrap: wrap; gap: var(--gap-xs); }
.choice__option { position: relative; }
.choice__option input {
    position: absolute; inset: 0;
    width: 100%; height: 100%; min-height: 0;
    margin: 0; opacity: 0; cursor: pointer;
}
.choice__label {
    display: block;
    min-height: 44px; padding: .65rem .7rem;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface);
    font-size: .875rem; white-space: nowrap;
}
.choice__option input:checked + .choice__label {
    border-color: var(--accent); background: var(--accent-wash);
    color: var(--accent); font-weight: 600;
}
.choice__option input:focus-visible + .choice__label { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Not a bare checkbox: a whole row that takes a tap anywhere along it. */
.toggle {
    display: flex; align-items: center; gap: var(--gap-sm);
    min-height: 44px; padding: .5rem .75rem;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
}
.toggle input { width: 1.15rem; height: 1.15rem; min-height: 0; margin: 0; accent-color: var(--accent); }

.form__actions { margin-top: var(--gap-lg); }

/* Narrow and centred: there is nothing on these pages but the form. */
.form--narrow { max-width: 21rem; margin: 0 auto; }

.alt { margin-top: var(--gap-lg); color: var(--ink-soft); font-size: .9rem; text-align: center; }

/* The two steps under the sign-in button. Numbered because the order is the
   whole instruction. */
.steps {
    margin: var(--gap) 0 var(--gap-lg); padding-left: 1.2rem;
    color: var(--ink-soft); font-size: .9rem;
}

.steps li + li { margin-top: .35rem; }

.notice {
    padding: .75rem .85rem; margin: 0 0 var(--gap);
    border: 1px solid var(--accent); border-radius: var(--radius);
    background: var(--accent-wash);
}

/* ---------------------------------------------------------------- badges */

.badge {
    display: inline-flex; align-items: center;
    padding: .15rem .55rem;
    border: 1px solid transparent; border-radius: var(--radius-pill);
    font-size: .8rem; font-weight: 600;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

.badge--free { background: var(--free-wash); border-color: var(--free); color: var(--free); }
.badge--last { background: var(--last-wash); border-color: var(--last); color: var(--last); }
.badge--full { background: var(--full-wash); border-color: var(--full); color: var(--full); }
.badge--playing { background: var(--free-wash); border-color: var(--free); color: var(--free); }
.badge--waiting { background: var(--full-wash); border-color: var(--full); color: var(--full); }

.badge__note { color: var(--ink-soft); font-size: .75rem; white-space: nowrap; }

/* How well somebody says they play. Deliberately quiet: the seat count is the
   badge worth colour on these pages, and two coloured pills in one line make
   neither of them mean anything. */
.level {
    display: inline-flex; align-items: center; gap: .3rem;
    margin-left: .35rem; padding: .05rem .4rem;
    border-radius: var(--radius-pill);
    background: var(--surface-sunk); color: var(--ink-soft);
    font-size: .75rem; font-weight: 600;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

.level__name { font-weight: 400; }

/* ----------------------------------------------------------------- lists */

.cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--gap-sm); }

/* Sticky, so a long scroll never leaves somebody wondering which day they are
   looking at. */
.day-heading {
    position: sticky; top: 0; z-index: 2;
    margin: var(--gap-lg) 0 var(--gap-sm);
    padding: .35rem 0;
    background: var(--ground);
    color: var(--ink-soft);
    font-size: .75rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .07em;
}
.day-heading:first-of-type { margin-top: 0; }

/* ----------------------------------------------------------------- cards */

.card {
    display: grid;
    grid-template-columns: 4.25rem minmax(0, 1fr) auto;
    gap: var(--gap-xs) var(--gap-sm);
    padding: var(--gap-sm) .85rem;
    border: 1px solid var(--line); border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow);
}

/* A game you are on is marked twice over: this outline, and the word "you"
   among the names. */
.card--mine { border-color: var(--accent); box-shadow: var(--shadow), inset 0 0 0 1px var(--accent); }

.card__when { display: flex; flex-direction: column; }
.card__from { font-size: 1.05rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.card__to { color: var(--ink-soft); font-size: .9rem; font-variant-numeric: tabular-nums; }
.card__length { color: var(--ink-soft); font-size: .75rem; }

.card__what { min-width: 0; }
.card__court { display: block; font-weight: 600; color: inherit; text-decoration: none; overflow-wrap: anywhere; }
.card__court:hover { text-decoration: underline; }
.card__players, .card__owner, .card__note { margin: .1rem 0 0; color: var(--ink-soft); font-size: .8rem; overflow-wrap: anywhere; }
.card__note { color: var(--accent); font-weight: 600; }

.card__counts { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }

.card__act { grid-column: 2 / -1; display: flex; justify-content: flex-end; margin-top: var(--gap-xs); }

.cards--past .card { opacity: .7; box-shadow: none; }

/* ----------------------------------------------------- one game, up close */

.game-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--gap-sm); margin: 0 0 var(--gap-xs); }
.game-head__time { font-size: 1.6rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.game-head__day, .game-head__length { color: var(--ink-soft); }
.game-head__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-sm); margin: 0 0 var(--gap-lg); }
.game-head__owner { color: var(--ink-soft); font-size: .875rem; }

/* Four rows, always four. How many people are still missing is something to
   see, not to count. */
.slots { list-style: none; margin: 0 0 var(--gap-lg); padding: 0; display: flex; flex-direction: column; gap: var(--gap-xs); }
.slot {
    display: flex; align-items: center; gap: var(--gap-sm);
    min-height: 48px; padding: .5rem .85rem;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface);
}
.slot--free { border-style: dashed; background: transparent; color: var(--ink-soft); }
.slot__number { min-width: 1rem; color: var(--ink-soft); font-size: .8rem; font-variant-numeric: tabular-nums; }
.slot__name { font-weight: 500; overflow-wrap: anywhere; }
.slot--free .slot__name { font-weight: 400; }
.slot__you {
    padding: .1rem .45rem;
    border-radius: var(--radius-pill);
    background: var(--accent); color: var(--accent-ink);
    font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}

.queue { list-style: none; margin: 0 0 var(--gap-lg); padding: 0; display: flex; flex-direction: column; gap: 2px; }
.queue__item {
    display: flex; align-items: center; gap: var(--gap-sm);
    padding: .55rem .85rem;
    border-radius: var(--radius);
    background: var(--surface-sunk);
}
.queue__number { min-width: 1.4rem; color: var(--ink-soft); font-size: .8rem; font-variant-numeric: tabular-nums; }

/* Sticks to the bottom of the viewport while there is page left to scroll and
   sits in the flow on a short page. Either way it clears the nav bar. */
.action {
    position: sticky;
    bottom: calc(var(--bar) + env(safe-area-inset-bottom) + var(--gap-sm));
    margin: var(--gap-lg) 0 0;
}
.action__note { margin: var(--gap-sm) 0 0; color: var(--ink-soft); font-size: .875rem; text-align: center; }

@media (min-width: 40rem) {
    .action { position: static; }
}

/* ------------------------------------------------------------ empty state */

/* Never a blank page: one sentence saying what is missing, one button leading
   to the thing that fixes it. */
.empty {
    padding: var(--gap-lg) var(--gap);
    border: 1px dashed var(--line); border-radius: var(--radius-lg);
    text-align: center;
}
.empty__text { margin: 0 0 var(--gap); color: var(--ink-soft); }

/* -------------------------------------------------------------- footnote */

.footnote { margin-top: var(--gap-lg); display: flex; gap: var(--gap); font-size: .875rem; }
