/*
    Mobile first, and specifically designed for the maintainer's real moment:
    standing at a field, in sunlight, holding a phone in one hand.

    That drives three concrete choices:
      - tap targets are at least 52px, so they can be hit with a thumb while
        walking;
      - form fields are at least 16px, because anything smaller makes iOS zoom
        the page on focus and the user loses their place;
      - contrast is high on a light background, because a phone screen in direct
        sunlight washes out dark themes.
*/

:root {
    --bg: #ffffff;
    --surface: #f6f8fa;
    --ink: #14171a;
    --muted: #5b6570;
    --line: #d5dbe2;
    --accent: #0b4f9c;
    --accent-ink: #ffffff;
    --danger: #b3261e;
    --warn-bg: #fff4e0;
    --warn-ink: #7a4a00;
    --ok: #1c6b32;
    --radius: 10px;
    --tap: 52px;
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

body {
    background: var(--bg);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 17px;
    line-height: 1.45;
    -webkit-text-size-adjust: 100%;
}

.app {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

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

.app-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 10;
}

.app-brand {
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ink);
    text-decoration: none;
    letter-spacing: -0.01em;
}

/*
    Who is signed in, sitting next to the way out. One group rather than two
    loose children, because the header spreads its children apart and the name
    would otherwise land in the middle of the bar.
*/
.app-account {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.app-user {
    font-size: 0.85rem;
    color: var(--muted);

    /* A long address must not push the sign-out button off the edge. */
    max-width: 11rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-main {
    flex: 1;
    width: 100%;
    max-width: 44rem;
    margin: 0 auto;
    padding: 1rem 1rem 3rem;
}

/* ------------------------------------------------------------ structure */

h1 {
    font-size: 1.45rem;
    margin: 0.25rem 0 0.25rem;
    letter-spacing: -0.02em;
}

h2 {
    font-size: 1.1rem;
    margin: 1.75rem 0 0.5rem;
    color: var(--muted);
    font-weight: 600;
}

.subtitle {
    color: var(--muted);
    margin: 0 0 1.25rem;
}

.card {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1rem;
    margin-bottom: 1rem;
    background: var(--surface);
}

.muted {
    color: var(--muted);
}

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

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: var(--tap);
    padding: 0 1.1rem;
    font-size: 1rem;
    font-weight: 600;
    font-family: inherit;
    border-radius: var(--radius);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    line-height: 1;
}

.btn-primary {
    background: var(--accent);
    color: var(--accent-ink);
}

.btn-secondary {
    background: var(--bg);
    color: var(--ink);
    border-color: var(--line);
}

.btn-ghost {
    background: transparent;
    color: var(--muted);
    border-color: transparent;
    min-height: 40px;
    font-weight: 500;
}

.btn-block {
    width: 100%;
}

.btn:disabled {
    opacity: 0.5;
    cursor: default;
}

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

/* ---------------------------------------------------------------- fields */

.field {
    margin-bottom: 1.1rem;
}

.field label {
    display: block;
    font-weight: 600;
    margin-bottom: 0.35rem;
    font-size: 0.95rem;
}

.field .hint {
    display: block;
    color: var(--muted);
    font-size: 0.85rem;
    margin-top: 0.3rem;
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="date"],
input[type="time"],
select {
    width: 100%;
    min-height: var(--tap);
    padding: 0 0.75rem;

    /* 16px minimum: below this iOS zooms the page on focus. */
    font-size: 1rem;
    font-family: inherit;
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

/* ------------------------------------------------------- day picker */

.day-picker {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.35rem;
}

.day {
    min-height: var(--tap);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--ink);
    cursor: pointer;
    font-family: inherit;
}

.day[aria-pressed="true"] {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
}

/* Per-day times. The common case is a different time on one day, so the name
   is stated rather than implied by column position. */
.day-time-row {
    display: grid;
    grid-template-columns: 6.5rem 1fr 1fr;
    gap: 0.5rem;
    align-items: center;
    margin-bottom: 0.5rem;
}

.day-time-name {
    font-weight: 600;
    font-size: 0.95rem;
}

/* ----------------------------------------------------------- time row */

.time-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}

/* --------------------------------------------------------------- events */

.events {
    list-style: none;
    margin: 0;
    padding: 0;
}

.event {
    display: flex;
    gap: 0.9rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--line);
}

.event:last-child {
    border-bottom: none;
}

/* The whole event row is the link, so the tap target matches what the eye
   reads as one item. Colour is inherited so the row does not turn into a
   page of blue underlined text. */
.event-link {
    display: flex;
    gap: 0.9rem;
    flex: 1;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    align-items: flex-start;
}

.event-link:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius);
}

.event-when {
    flex: 0 0 5.5rem;
    font-variant-numeric: tabular-nums;
}

.event-day {
    font-weight: 700;
    font-size: 0.95rem;
}

.event-time {
    color: var(--muted);
    font-size: 0.9rem;
}

.event-what {
    flex: 1;
    min-width: 0;
}

.event-title {
    font-weight: 600;
}

.event-where {
    color: var(--muted);
    font-size: 0.9rem;
}

/* Cancelled practices are shown, not hidden. A parent who saw last week's
   schedule needs to see that it changed. */
.event-cancelled .event-title {
    text-decoration: line-through;
    color: var(--muted);
}

.badge {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 700;
    padding: 0.15rem 0.45rem;
    border-radius: 6px;
    margin-left: 0.4rem;
    vertical-align: 1px;
}

.badge-cancelled {
    background: var(--warn-bg);
    color: var(--warn-ink);
}

.badge-type {
    background: var(--surface);
    color: var(--muted);
    border: 1px solid var(--line);
}

/* The one chip that has to be noticed: practice is off. */
.badge-alert {
    background: var(--danger);
    color: #ffffff;
}

/* -------------------------------------------------------------- messages */

/*
    One card per message: what it was, when, and what it said. The chip is doing
    real work rather than decoration - somebody scanning this page is looking for
    one thing, and it is usually a cancellation.
*/
.message-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
}

/* The badge carries a left margin for sitting after a title; here it starts
   the line. */
.message-head .badge {
    margin-left: 0;
}

.message-when {
    color: var(--muted);
    font-size: 0.82rem;
    white-space: nowrap;
}

/* A stripe, so a cancelled date is visible without reading the card. */
.message-cancelled {
    border-left: 4px solid var(--danger);
}

/* ------------------------------------------------------------ game day */

/* Label on the left, value on the right, so a row scans as one fact. */
.row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    min-height: 2rem;
}

.row-label {
    color: var(--muted);
}

.row-value {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* An estimated time must never look like a known one. The value itself is
   italicised and muted, and the provenance note underneath says "Estimated".
   A parent reading a plain bold 9:45 PM has been told something nobody knows. */
.value-estimated {
    color: var(--muted);
    font-style: italic;
}

p.hint {
    color: var(--muted);
    font-size: 0.85rem;
    margin: 0.15rem 0 0.5rem;
}

/* A row of mutually exclusive answers a parent taps one-handed. They wrap
   rather than scroll, because a buried third option reads as "not offered". */
.choice-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.choice {
    flex: 1 1 auto;
    min-width: 5.5rem;
    padding: 0 0.75rem;
    font-size: 0.95rem;
    font-weight: 600;
}

/* -------------------------------------------------------------- messages */

.alert {
    border-radius: var(--radius);
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
    border: 1px solid;
}

.alert-error {
    background: #fdecea;
    border-color: #f3b6b0;
    color: var(--danger);
}

.alert-info {
    background: var(--surface);
    border-color: var(--line);
    color: var(--ink);
}

/* ---------------------------------------------------------------- states */

.empty {
    color: var(--muted);
    padding: 1.5rem 0;
    text-align: center;
}

/* Invite code. Large and letter-spaced because it gets read off a phone screen
   and retyped, or pasted into a group text. */.invite {
    margin-top: 1.5rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1rem;
    background: var(--surface);
}

.invite h3 {
    margin: 0 0 0.35rem;
    font-size: 1rem;
}

.invite-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1.7rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    margin: 0.6rem 0 0.9rem;
    word-break: break-all;
}

/* Pending guardianship claims, and the per-player claim button. */
.claims {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
}

.claim {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--line);
}

.claim:last-child {
    border-bottom: none;
}

.claim-actions {
    display: flex;
    gap: 0.4rem;
    flex-shrink: 0;
}

/* A checkbox that is comfortable to hit with a thumb. */
.checkbox-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-height: var(--tap);
    font-weight: 600;
}

.checkbox-row input[type="checkbox"] {
    width: 1.4rem;
    height: 1.4rem;
    flex: 0 0 auto;
}

/* Shown when the calendar runs out of announced practices.
   It must not look like "there is no practice" — see the note in Calendar.razor. */
.not-announced {
    margin-top: 1.5rem;
    border: 1px dashed var(--line);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    color: var(--muted);
    background: var(--surface);
}

.not-announced strong {
    color: var(--ink);
}

.loading {
    color: var(--muted);
    padding: 2rem 0;
    text-align: center;
}

.actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
}

.team-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.team-list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--tap);
    padding: 0.5rem 0.9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 0.5rem;
    color: var(--ink);
    text-decoration: none;
    font-weight: 600;
}

.team-role {
    color: var(--muted);
    font-weight: 500;
    font-size: 0.85rem;
}

/* --------------------------------------------------------- error boundary */

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}
