/*
 * The web interface of Turkish for Work.
 *
 * Three constraints shaped it and are worth stating, because they are easy to undo by accident:
 *
 *  1. The learner reads long English sentences on it for an hour at a time, so the measure is limited (about 70
 *     characters), the base size is 17 px and the line height is generous. Exercise text is one step larger again.
 *  2. Light and dark follow the browser. An account can override it in Настройки, which sets data-theme on <html>;
 *     both the media query and the attribute set the same tokens, so nothing has to be kept in two places.
 *  3. The primary action of an exercise is pinned to the bottom of the viewport and never scrolls away — that is the
 *     one complaint the desktop runner was rebuilt around («не видна нижняя кнопка подтверждения»), and a browser makes
 *     it easy to reintroduce.
 *
 * It must read at 1280 px (sidebar + content) and on a phone (one column, 16 px gutters, no horizontal scroll).
 */

/*
 * The palette is the brand's (brand/README.md): teal #0C6E72 / #2BB6B9, cobalt #1B3A6B, gold #A8761E, coral #C8442E
 * (sparingly: steps and accents), cream #F4EFE6, ink #0B1A22. The light theme stands on cream, the dark on ink, and
 * both carry the brand's star-and-arch pattern as the page ground (img/brand/pattern-*.svg, generated with the rest
 * of the brand by brand/src/build.mjs).
 *
 * Text colours are checked against their own ground for AA: teal #0C6E72 on cream 5.1:1, the text gold is darkened
 * to #8A5F14 (4.8:1) because the brand gold #A8761E gives only 3.4:1; on ink, #2BB6B9 is 7.2:1 and #D6A650 8.0:1.
 * Gold is a highlight, never the colour of a surface; coral marks the top step (C1) and errors, nothing else.
 */
:root {
    --bg: #f4efe6;
    --pattern: url("../img/brand/pattern-light.svg");
    --surface: #fbf8f2;
    --surface-2: #ede6d8;
    --fg: #0b1a22;
    --muted: #55646a;
    --line: #ddd4c4;
    --accent: #0c6e72;
    --accent-fg: #ffffff;
    --accent-soft: #d7eae7;
    --deep: #1b3a6b;
    --deep-soft: #dfe5ef;
    --gold: #8a5f14;
    --gold-fg: #ffffff;
    --gold-soft: #f1e4c8;
    --coral: #c8442e;
    --ok: #146b4d;
    --ok-soft: #ddeedf;
    --warn: #8a5f14;
    --warn-soft: #f1e4c8;
    --error: #a6311f;
    --error-soft: #f5ddd6;
    --radius: 10px;
    --shadow: 0 1px 2px rgba(11, 26, 34, .06), 0 4px 16px rgba(11, 26, 34, .07);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --bg: #0b1a22;
        --pattern: url("../img/brand/pattern-dark.svg");
        --surface: #11252e;
        --surface-2: #17303a;
        --fg: #ede7dc;
        --muted: #9aaeb3;
        --line: #24404a;
        --accent: #2bb6b9;
        --accent-fg: #062326;
        --accent-soft: #12383c;
        --deep: #8fa9d6;
        --deep-soft: #1a2a45;
        --gold: #d6a650;
        --gold-fg: #14100a;
        --gold-soft: #33291a;
        --coral: #e8725c;
        --ok: #6cc08d;
        --ok-soft: #173222;
        --warn: #d6a650;
        --warn-soft: #33291a;
        --error: #ff8e7a;
        --error-soft: #3a1f1a;
        --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 4px 16px rgba(0, 0, 0, .4);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #0b1a22;
    --pattern: url("../img/brand/pattern-dark.svg");
    --surface: #11252e;
    --surface-2: #17303a;
    --fg: #ede7dc;
    --muted: #9aaeb3;
    --line: #24404a;
    --accent: #2bb6b9;
    --accent-fg: #062326;
    --accent-soft: #12383c;
    --deep: #8fa9d6;
    --deep-soft: #1a2a45;
    --gold: #d6a650;
    --gold-fg: #14100a;
    --gold-soft: #33291a;
    --coral: #e8725c;
    --ok: #6cc08d;
    --ok-soft: #173222;
    --warn: #d6a650;
    --warn-soft: #33291a;
    --error: #ff8e7a;
    --error-soft: #3a1f1a;
    --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 4px 16px rgba(0, 0, 0, .4);
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg) var(--pattern) repeat;
    color: var(--fg);
    font: 17px/1.6 system-ui, "Segoe UI", Roboto, Arial, sans-serif;
    -webkit-text-size-adjust: 100%;
}

a { color: var(--accent); }
a:hover { text-decoration: underline; }

/* ───────────── shell ───────────── */

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

header.top {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 5;
}

/*
 * The brand lockup: the star-and-staircase mark (img/brand/mark.svg) and the wordmark set in type — «Turkish» in the
 * text colour, «for Work» in the accent — with the tagline under it, as in brand/index.html.
 */
header.top .brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 650;
    text-decoration: none;
    color: var(--fg);
    flex: 0 1 auto;
    min-width: 0;
}

.brand-mark { display: block; flex: 0 0 auto; width: 30px; height: 30px; }
.brand-name { letter-spacing: -.005em; white-space: nowrap; }
.brand-name b { color: var(--accent); font-weight: 750; }
header.top .brand:hover { text-decoration: none; }
header.top .brand:hover .brand-name { text-decoration: underline; }
header.top .top-nav { margin-left: auto; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
header.top .who { color: var(--muted); max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.body { flex: 1; display: flex; flex-direction: column; }

nav.side {
    display: flex;
    gap: 4px;
    overflow-x: auto;
    padding: 8px 16px;
    border-bottom: 1px solid var(--line);
    scrollbar-width: thin;
}

nav.side a {
    padding: 8px 12px;
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--fg);
    white-space: nowrap;
}

nav.side a:hover { background: var(--surface-2); text-decoration: none; }
nav.side a.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

main {
    padding: 20px 16px 96px;
    width: 100%;
    max-width: 860px;
    margin: 0 auto;
}

@media (min-width: 900px) {
    .body { flex-direction: row; align-items: flex-start; }

    nav.side {
        flex-direction: column;
        overflow: visible;
        border-bottom: none;
        border-right: 1px solid var(--line);
        width: 220px;
        flex: 0 0 220px;
        padding: 20px 12px;
        position: sticky;
        top: 53px;
        align-self: stretch;
        min-height: calc(100vh - 53px);
    }

    main { padding: 28px 32px 120px; }
}

/* ───────────── typography ───────────── */

h1 { font-size: 1.55rem; line-height: 1.25; margin: 0 0 6px; }
h2 { font-size: 1.2rem; margin: 32px 0 10px; }
h3 { font-size: 1.02rem; margin: 20px 0 8px; }
p { max-width: 70ch; }
.muted { color: var(--muted); }
.small { font-size: .9rem; }
.tiny { font-size: .82rem; }
.error { color: var(--error); }
.ok { color: var(--ok); }
.warn { color: var(--warn); }
.center { text-align: center; }

/* ───────────── cards, lists, tables ───────────── */

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

.card.flat { background: none; box-shadow: none; }
.card h3 { margin-top: 0; }

.grid { display: grid; gap: 12px; }
.grid.two { grid-template-columns: 1fr; }
.grid.three { grid-template-columns: 1fr; }

@media (min-width: 620px) {
    .grid.two { grid-template-columns: 1fr 1fr; }
    .grid.three { grid-template-columns: repeat(3, 1fr); }
}

.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.stat .label { color: var(--muted); font-size: .85rem; }
.stat .value { font-size: 1.35rem; font-weight: 650; }
.stat .note { color: var(--muted); font-size: .82rem; }

dl.numbers { display: grid; grid-template-columns: max-content 1fr; gap: 6px 20px; margin: 0; }
dl.numbers dt { color: var(--muted); }
dl.numbers dd { margin: 0; }

table { border-collapse: collapse; width: 100%; font-size: .95rem; }
table th, table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
table th { color: var(--muted); font-weight: 600; font-size: .85rem; }
.table-scroll { overflow-x: auto; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface);
    font-size: .85rem;
}

.chip.done { background: var(--ok-soft); color: var(--ok); border-color: transparent; }
.chip.current { background: var(--accent-soft); color: var(--accent); border-color: transparent; font-weight: 600; }

.bar { background: var(--surface-2); border-radius: 999px; height: 8px; overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--accent); }

/* ───────────── buttons ───────────── */

button, .btn {
    font: inherit;
    padding: 10px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--fg);
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

button:hover:not(:disabled), .btn:hover { background: var(--surface-2); text-decoration: none; }
button:disabled { opacity: .55; cursor: default; }

button.primary, .btn.primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-fg);
    font-weight: 600;
}

button.primary:hover:not(:disabled), .btn.primary:hover { filter: brightness(1.08); background: var(--accent); }

/* Gold is the brand's highlight, so a gold button is allowed once per screen — «Создать аккаунт», and nothing else. */
button.gold, .btn.gold {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--gold-fg);
    font-weight: 600;
}

button.gold:hover:not(:disabled), .btn.gold:hover { filter: brightness(1.08); background: var(--gold); }

button.quiet { background: none; border-color: transparent; color: var(--muted); }
button.quiet:hover:not(:disabled) { background: var(--surface-2); }

button.link { background: none; border: none; color: var(--accent); padding: 0; text-decoration: underline; }
button.link:hover:not(:disabled) { background: none; }

button.hero, .btn.hero {
    width: 100%;
    font-size: 1.12rem;
    padding: 18px 20px;
    text-align: center;
}

.row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.row.tight { gap: 6px; }

/* ───────────── forms ───────────── */

label.field { display: grid; gap: 4px; margin: 0 0 14px; max-width: 520px; }
label.check { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 14px; max-width: 70ch; }
label.check input { margin-top: 5px; flex: 0 0 auto; }
/* The explanation under a switch is its own paragraph, not a tail on the same line. */
label.check > span { display: grid; gap: 2px; }
label.field > span { display: block; }

input[type=text], input[type=password], input[type=email], input[type=number], input[type=url], input[type=search], select, textarea {
    font: inherit;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--fg);
    width: 100%;
    max-width: 520px;
}

textarea { min-height: 92px; resize: vertical; }
input:focus-visible, textarea:focus-visible, select:focus-visible, button:focus-visible, a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

form.auth { display: grid; gap: 12px; max-width: 420px; }
form.auth label { display: grid; gap: 4px; }
form.auth label.inline { display: flex; align-items: center; gap: 8px; }
form.inline { display: inline; }

/* ───────────── the session runner ───────────── */

.runner-top {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 16px;
    align-items: baseline;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 16px;
}

.runner-top .time { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; }
.runner-top .time.over { color: var(--warn); }

.exercise { font-size: 1.06rem; }
.exercise .instruction { color: var(--muted); font-size: .92rem; margin: 0 0 10px; }

.exercise .prompt {
    font-size: 1.32rem;
    line-height: 1.45;
    margin: 0 0 10px;
    max-width: 44ch;
}

.exercise .ru-cue { font-size: 1.15rem; margin: 0 0 12px; }
.exercise .en-card {
    font-size: 1.35rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin: 0 0 12px;
}

.options { display: grid; gap: 8px; margin: 14px 0; }

.options button {
    justify-content: flex-start;
    text-align: left;
    padding: 14px 16px;
    font-size: 1.04rem;
}

.options button .num {
    flex: 0 0 auto;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    min-width: 1.4em;
}

.options button.correct { background: var(--ok-soft); border-color: var(--ok); }
.options button.wrong { background: var(--error-soft); border-color: var(--error); }
.options button.dimmed { opacity: .55; }
.options button.selected { border-color: var(--accent); }

.ways { display: grid; gap: 8px; margin: 16px 0; }
.ways .way { justify-content: flex-start; text-align: left; padding: 12px 14px; flex-direction: column; align-items: flex-start; gap: 2px; }
.ways .way .label { font-weight: 600; }
.ways .way .explain { color: var(--muted); font-size: .88rem; font-weight: 400; }
.ways .way.primary { border-color: var(--accent); background: var(--accent-soft); }
.ways .objective { display: flex; flex-wrap: wrap; gap: 8px; }
.ways .objective .way { flex: 1 1 180px; }

.tiles { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.tiles button { padding: 8px 12px; }
.tiles button.placed { visibility: hidden; }

.built {
    min-height: 52px;
    border: 1px dashed var(--line);
    border-radius: var(--radius);
    padding: 10px 12px;
    background: var(--surface);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

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

.feedback { border-radius: var(--radius); padding: 14px 16px; margin: 16px 0; border: 1px solid var(--line); }
.feedback.right { background: var(--ok-soft); border-color: transparent; }
.feedback.wrong { background: var(--warn-soft); border-color: transparent; }
.feedback h3 { margin: 0 0 6px; }
.feedback .line { margin: 4px 0; }
.feedback .dots { font-size: 1.1rem; letter-spacing: .12em; }

.notice { background: var(--surface-2); border-radius: var(--radius); padding: 10px 14px; margin: 12px 0; font-size: .92rem; }
.notice.warn { background: var(--warn-soft); color: var(--warn); }
.notice.err { background: var(--error-soft); color: var(--error); }

.retry { color: var(--warn); margin: 8px 0; }
.hints { margin: 10px 0; padding-left: 20px; }
.hints li { margin: 2px 0; }

/* The pinned action row: the one button the learner is meant to press never scrolls away. */
.action-bar {
    position: sticky;
    bottom: 0;
    background: var(--bg);
    border-top: 1px solid var(--line);
    padding: 12px 0 14px;
    margin-top: 20px;
    z-index: 4;
}

.action-bar .keys { color: var(--muted); font-size: .82rem; margin-top: 8px; }
.action-bar .buttons { display: flex; flex-wrap: wrap; gap: 10px; }
.action-bar .buttons button.primary { flex: 1 1 220px; }

/* ───────────── interactive words (SPEC §10) ───────────── */

.itext { }
.itext .w { cursor: help; border-bottom: 1px dotted var(--line); }
.itext .w:hover { background: var(--accent-soft); border-bottom-color: var(--accent); }
.itext .w.known { border-bottom-style: solid; }
.itext .term { font-weight: 600; color: var(--accent); }

.word-popup {
    position: fixed;
    z-index: 30;
    max-width: 320px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 12px 14px;
    font-size: .95rem;
}

.word-popup .word { font-weight: 650; font-size: 1.05rem; }
.word-popup .ipa { color: var(--muted); font-style: italic; }
.word-popup .tr { margin-top: 4px; }
.word-popup .meta { color: var(--muted); font-size: .84rem; margin-top: 4px; }
.word-popup .ai { border: 1px solid var(--line); border-radius: 4px; padding: 0 4px; font-size: .72rem; }
.word-popup .close { position: absolute; top: 4px; right: 6px; }

/* ───────────── charts (Прогресс) ───────────── */

.chart { width: 100%; height: auto; }
.chart .grid-line { stroke: var(--line); stroke-width: 1; }
.chart .series { fill: none; stroke: var(--accent); stroke-width: 2; }
.chart .series.alt { stroke: var(--ok); }
.chart .bar-rect { fill: var(--accent); }
.chart text { fill: var(--muted); font-size: 10px; }

.skill-row { display: grid; grid-template-columns: minmax(120px, 1fr) 2fr max-content; gap: 10px; align-items: center; margin: 6px 0; }

/* ───────────── misc ───────────── */

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 10px 16px;
    background: var(--gold-soft);
    color: var(--fg);
    z-index: 100;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* SPEC §23.2 — «Ответить голосом»: the level meter and the timer of the browser recorder.
   The meter is a plain div whose width is set from the audio thread's peak, not a canvas: it has to be readable at a
   glance while the learner is speaking, and it has to keep working when the page is redrawn by Blazor mid-utterance. */
.voice-recorder { margin: 10px 0; }

.voice-meter {
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
    margin: 10px 0 4px;
    max-width: 420px;
}

.voice-meter-fill {
    height: 100%;
    background: var(--accent);
    border-radius: 999px;
    transition: width 80ms linear;
}

.voice-timer { font-variant-numeric: tabular-nums; color: var(--muted); font-size: .9rem; }

/* ───────────── the model picker (Настройки → AI-провайдеры) ─────────────
   OpenRouter alone serves several hundred models, so the list is a searched list and not a <select>: rows are plain
   buttons, the id is the loud part (it is what has to be typed elsewhere), and the facts the catalogue gave — context
   window, price — are a quiet second line. The list scrolls inside itself so the rest of the page stays reachable. */

ul.model-list {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    display: grid;
    gap: 6px;
    max-height: 340px;
    overflow-y: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 6px;
    background: var(--bg);
}

ul.model-list button.model {
    display: grid;
    gap: 2px;
    width: 100%;
    /* The base button rule centres its content; a list row is read down its left edge, so both axes are reset. */
    justify-content: start;
    justify-items: start;
    text-align: left;
    padding: 8px 10px;
    border-color: transparent;
    background: none;
}

ul.model-list button.model:hover { background: var(--surface-2); }
ul.model-list button.model.current { background: var(--accent-soft); border-color: var(--accent); }
ul.model-list button.model .id { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: .9rem; }
ul.model-list button.model .name,
ul.model-list button.model .facts { color: var(--muted); font-size: .82rem; }

/* ───────────── sign-in, registration, invitations ─────────────
   These pages are the first thing a new learner sees, and until this ticket they were a bare form on a white page with
   no idea what the product was. Two columns from 860 px (the form, and one paragraph saying what this is), one column
   on a phone with the form first — the person who came here to sign in should not scroll past marketing to do it. */

main.auth-main { max-width: 1000px; margin: 0 auto; padding: 32px 16px 48px; width: 100%; }

/* The lockup above the form, at the size the landing page uses it: arriving from «Войти» must not feel like leaving
   the site. The tagline is the brand's own, letterspaced the way the asset letterspaces it. */
.auth-brand { display: flex; align-items: center; gap: 14px; margin: 0 0 24px; color: var(--fg); text-decoration: none; width: max-content; max-width: 100%; }
.auth-brand:hover { text-decoration: none; }
.auth-brand:hover .name { text-decoration: underline; }
.auth-brand img { display: block; width: 46px; height: 46px; }
.auth-brand .lockup { display: grid; gap: 2px; }
.auth-brand .name { font-size: 1.35rem; font-weight: 700; letter-spacing: -.01em; line-height: 1.1; }
.auth-brand .name b { color: var(--accent); font-weight: 800; }
.auth-brand .tag { font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }

.auth-wrap { display: grid; gap: 28px; align-items: start; }

@media (min-width: 860px) {
    .auth-wrap { grid-template-columns: minmax(0, 420px) minmax(0, 1fr); gap: 56px; }
}

.auth-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 24px;
    box-shadow: var(--shadow);
}

.auth-card h1 { font-size: 1.7rem; margin-bottom: 4px; }
.auth-card .auth-lede { color: var(--muted); margin: 0 0 20px; font-size: .95rem; }
.auth-card form.auth { max-width: none; gap: 14px; }
.auth-card form.auth input { max-width: none; }
.auth-card form.auth button[type=submit] { margin-top: 4px; }
.auth-card .auth-links { margin: 18px 0 0; padding-top: 16px; border-top: 1px solid var(--line); font-size: .92rem; }
.auth-card .auth-links p { margin: 0 0 6px; }
.auth-card .auth-links p:last-child { margin-bottom: 0; }

/* The validation summary is a live region, so a screen reader hears «Неверная почта или пароль» instead of the
   sighted-only red text. It is rendered on every page load, so it must draw nothing at all until it has something to
   say — ASP.NET marks the quiet state with .validation-summary-valid, and an element with only an empty <ul> inside
   is not :empty, which is why that class and not the pseudo-class is what hides it. */
.validation.validation-summary-valid,
.validation:empty { display: none !important; }

.validation {
    background: var(--error-soft);
    color: var(--error);
    border-radius: var(--radius);
    padding: 10px 14px;
    font-size: .92rem;
}

.validation ul { margin: 0; padding-left: 18px; }
.validation li { list-style: disc; }

.auth-note { border-radius: var(--radius); padding: 12px 14px; font-size: .92rem; margin: 0 0 18px; }
.auth-note.closed { background: var(--warn-soft); color: var(--warn); }
.auth-note.invited { background: var(--ok-soft); color: var(--ok); }
.auth-note.first { background: var(--accent-soft); color: var(--accent); }

.auth-aside { color: var(--muted); }
.auth-aside h2 { margin-top: 0; font-size: 1.05rem; color: var(--fg); }
.auth-aside ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; max-width: 46ch; }
.auth-aside ul li { padding-left: 18px; position: relative; }
.auth-aside ul li::before { content: "—"; position: absolute; left: 0; color: var(--accent); }
.auth-aside .pitch { color: var(--fg); font-size: 1.05rem; max-width: 40ch; }

/* ───────────── the admin screen ───────────── */

table.accounts { width: 100%; border-collapse: collapse; margin: 0 0 18px; font-size: .94rem; }
table.accounts th, table.accounts td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.accounts th { color: var(--muted); font-weight: 600; font-size: .85rem; }
table.accounts td .row { gap: 6px; }
table.accounts code { font-size: .85rem; word-break: break-all; }

.invite-link {
    display: block;
    background: var(--surface-2);
    border-radius: var(--radius);
    padding: 10px 12px;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: .85rem;
    word-break: break-all;
    margin: 8px 0;
}

@media (max-width: 620px) {
    table.accounts, table.accounts tbody, table.accounts tr, table.accounts td { display: block; width: 100%; }
    table.accounts thead { display: none; }
    table.accounts tr { border: 1px solid var(--line); border-radius: var(--radius); margin: 0 0 10px; padding: 6px 0; }
    table.accounts td { border: none; padding: 4px 12px; }
}

/* The skip link is invisible until it is focused, and then it has to be a real, visible target. */
a.sr-only:focus-visible {
    position: fixed;
    top: 8px;
    left: 8px;
    width: auto;
    height: auto;
    clip: auto;
    padding: 8px 12px;
    background: var(--accent);
    color: var(--accent-fg);
    border-radius: var(--radius);
    z-index: 200;
}

/* ── SPEC §26: the day-by-day calendar ─────────────────────────────────────────────────────────────────────
   A grid, not a chart, because a day with nothing in it has to occupy space to be seen. Rows are weekdays and
   columns are weeks: the cells are emitted week by week and `grid-auto-flow: column` lays them out that way, so
   the markup order is the calendar order and no transposition happens in the view.
   Shades are one accent colour at four opacities rather than four colours — a missed day must not read as an
   error, and nothing here may look like a scoreboard (SPEC §0). */
.calendar { display: flex; gap: 8px; align-items: flex-start; margin: 4px 0 10px; overflow-x: auto; padding-bottom: 4px; }

.cal-side { display: grid; grid-template-rows: 14px repeat(7, 14px); gap: 3px; flex: 0 0 auto; }
.cal-side span { font-size: .68rem; line-height: 14px; color: var(--muted); text-align: right; width: 1.6em; }

.cal-body { flex: 0 0 auto; }

.cal-months { display: grid; grid-auto-flow: column; grid-auto-columns: 14px; gap: 3px; height: 14px; }
.cal-months span { font-size: .68rem; line-height: 14px; color: var(--muted); white-space: nowrap; }

.cal-grid { display: grid; grid-template-rows: repeat(7, 14px); grid-auto-flow: column; grid-auto-columns: 14px; gap: 3px; }

.cal-day { width: 14px; height: 14px; border-radius: 3px; background: var(--surface-2); border: 1px solid transparent; }
.cal-day.l0 { background: transparent; border-color: var(--line); }
.cal-day.l1 { background: color-mix(in srgb, var(--accent) 25%, var(--surface)); }
.cal-day.l2 { background: color-mix(in srgb, var(--accent) 50%, var(--surface)); }
.cal-day.l3 { background: color-mix(in srgb, var(--accent) 75%, var(--surface)); }
.cal-day.l4 { background: var(--accent); }
/* Outside the goal or still to come: the cell holds its place in the row and says nothing. */
.cal-day.outside { background: color-mix(in srgb, var(--fg) 7%, transparent); border-color: transparent; }
/* Today, before anything has been done — an outline, not a reproach. */
.cal-day.pending { background: transparent; border-style: dashed; border-color: var(--muted); }
.cal-day.today { outline: 2px solid var(--fg); outline-offset: 1px; }

.cal-legend { display: flex; align-items: center; gap: 4px; margin: 0 0 6px; }
.cal-legend .cal-day { width: 12px; height: 12px; }
.cal-legend span:first-child { margin-right: 4px; }
.cal-legend span:last-child { margin-left: 4px; }

/* A day with no study is dimmed in the table, never struck through or coloured as a failure. */
tr.idle td { color: var(--muted); }

@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .cal-day.l1 { background: var(--accent-soft); }
    .cal-day.l2 { background: var(--accent-soft); opacity: .75; }
    .cal-day.l3 { background: var(--accent); opacity: .7; }
}

/* ───────────── Ступени (docs/TZ.md §5) ─────────────
 * Five rungs, one per step, with the brand's step icons. Closed is green with its date, the current step is teal, the
 * rest is quiet. Nothing is red: an open condition is work ahead, and «не измерено» is not a failure (TZ §9).
 */
.steps-ladder {
    list-style: none;
    margin: 0 0 8px;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
}

.step-rung {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 8px 4px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface);
    text-align: center;
    min-width: 0;
}

.step-rung .step-name { font-weight: 650; }
.step-rung .step-when { color: var(--muted); overflow-wrap: anywhere; }
.step-rung.closed { background: var(--ok-soft); border-color: transparent; }
.step-rung.closed .step-when { color: var(--ok); }
.step-rung.current { background: var(--accent-soft); border-color: var(--accent); }
.step-rung.current .step-when { color: var(--accent); font-weight: 600; }
.step-rung.ahead img { opacity: .55; }

.step-remaining { margin: 4px 0; }

.step-card.current { border-color: var(--accent); }
.step-card.closed summary .small { color: var(--ok); }
.step-head { display: flex; gap: 12px; align-items: flex-start; }
.step-head h2 { margin: 0 0 4px; }
details.step-card summary { cursor: pointer; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

.step-criteria { list-style: none; margin: 12px 0 0; padding: 0; }
.step-criterion { padding: 10px 0; border-top: 1px solid var(--line); }
.step-criterion p { margin: 4px 0 0; }
.crit-line { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.crit-state { padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--muted); white-space: nowrap; }
.step-criterion.passed .crit-state { background: var(--ok-soft); color: var(--ok); }
.step-criterion.unmeasured .crit-state { background: var(--deep-soft); color: var(--deep); }
.crit-bar { display: block; position: relative; margin: 6px 0 0; }
.step-criterion.passed .crit-bar > span { background: var(--ok); }
.crit-mark { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--fg); opacity: .45; }

.can-do { list-style: none; margin: 8px 0 0; padding: 0; }
.can-do li { display: flex; justify-content: space-between; gap: 10px; padding: 4px 0; font-size: .92rem; }
.can-do li.said span:first-child { color: var(--ok); }
.can-do li.said span:first-child::before { content: "✓ "; }

.step-forecast { margin: 12px 0 0; }
/* ── First steps (docs/TZ.md §4.4): the alphabet cards and the harmony drill ── */
.letters { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; margin: 12px 0 20px; }
.letters .letter { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; background: var(--surface); }
.letters .letter.surprising { border-color: var(--accent); background: var(--accent-soft); }
.letters .letter .glyph { font-size: 1.6rem; font-weight: 600; letter-spacing: .04em; }
.letters .letter .example { margin-top: 6px; }
.letters.compact { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.letters.compact .letter .glyph { font-size: 1.25rem; }
.quiz-shown { font-size: 1.5rem; font-weight: 600; margin: 6px 0 10px; }
