/* kinderTant — app styles. Hand-written, no build step. */

/*
 * Colour is named by what it is for, not by what it looks like, so the dark
 * palette below can swap every value without a single rule needing to know.
 * A room at seven in the morning in winter is dark; so is a phone checked in
 * bed after a late collection.
 */
:root {
    --brand: #1f9d76;
    --brand-dark: #17795b;
    --brand-soft: #e7f6f1;
    --accent: #f59e0b;

    --danger: #dc2626;
    --danger-soft: #fee2e2;
    --danger-line: #fecaca;
    --danger-ink: #b91c1c;
    --warn-soft: #fef3c7;
    --warn-ink: #92400e;
    --info-soft: #eef2ff;
    --info-ink: #4338ca;

    --ink: #0f172a;
    --ink-2: #334155;
    --muted: #64748b;
    --line: #e2e8f0;
    --line-strong: #cbd5e1;
    --bg: #f6f7f9;
    --surface: #ffffff;
    --surface-2: #f8fafc;      /* a panel sitting on a card */
    --hover: #f1f5f9;
    --scroll-thumb: #d7dee6;
    --scroll-thumb-hover: #c2ccd6;
    --toast-bg: #0f172a;
    --toast-ink: #ffffff;
    --skeleton: #eef1f5;

    /*
     * The wash behind a page that is only one card wide — sign in, the public
     * application, the door screen. These have to be tokens like everything
     * else: the card on top follows the palette, so a fixed light wash leaves
     * a dark card floating on a white page, which is exactly how it looked.
     */
    --wash-1: #eefaf6;
    --wash-2: #f6f7f9;
    /* The edge of a brand-soft panel. */
    --brand-line: #bfe6d9;

    --radius: 14px;
    --radius-sm: 9px;
    --shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 8px 24px rgba(15, 23, 42, .06);
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .08);
    --nav-w: 248px;
    --nav-w-rail: 66px;
    --tabbar-h: 62px;
    --motion: .12s;
    color-scheme: light;
}

/*
 * Dark is not the light palette inverted. Surfaces lift as they come forward
 * rather than getting whiter, text stops short of pure white so it does not
 * glare, and the status colours are re-picked for contrast rather than dimmed:
 * a late badge that has gone muddy is a late badge nobody reads.
 */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --brand: #34c79a;
        --brand-dark: #6ee7c0;
        --brand-soft: #123c31;

        --danger: #f87171;
        --danger-soft: #3b1618;
        --danger-line: #7f1d1d;
        --danger-ink: #fca5a5;
        --warn-soft: #3b2f0e;
        --warn-ink: #fcd34d;
        --info-soft: #1e1b4b;
        --info-ink: #a5b4fc;

        --ink: #e8edf4;
        --ink-2: #c2ccd9;
        --muted: #8d9bad;
        --line: #26303d;
        --line-strong: #3a4655;
        --bg: #0b1017;
        --surface: #141b24;
        --surface-2: #1b232e;
        --hover: #222c38;
        --scroll-thumb: #2f3a48;
        --scroll-thumb-hover: #3f4c5c;
        --toast-bg: #e8edf4;
        --toast-ink: #0b1017;
        --skeleton: #1e2733;

        /* Keeps the faint green cast of the light wash without lifting the
           page off the dark background the cards sit on. */
        --wash-1: #10211c;
        --wash-2: #0b1017;
        --brand-line: #1d5a49;

        --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 8px 24px rgba(0, 0, 0, .4);
        --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
        color-scheme: dark;
    }
}

/* The toggle wins over the system in both directions. */
:root[data-theme="dark"] {
    --brand: #34c79a;
    --brand-dark: #6ee7c0;
    --brand-soft: #123c31;

    --danger: #f87171;
    --danger-soft: #3b1618;
    --danger-line: #7f1d1d;
    --danger-ink: #fca5a5;
    --warn-soft: #3b2f0e;
    --warn-ink: #fcd34d;
    --info-soft: #1e1b4b;
    --info-ink: #a5b4fc;

    --ink: #e8edf4;
    --ink-2: #c2ccd9;
    --muted: #8d9bad;
    --line: #26303d;
    --line-strong: #3a4655;
    --bg: #0b1017;
    --surface: #141b24;
    --surface-2: #1b232e;
    --hover: #222c38;
    --scroll-thumb: #2f3a48;
    --scroll-thumb-hover: #3f4c5c;
    --toast-bg: #e8edf4;
    --toast-ink: #0b1017;
    --skeleton: #1e2733;

    --wash-1: #10211c;
    --wash-2: #0b1017;
    --brand-line: #1d5a49;

    --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 8px 24px rgba(0, 0, 0, .4);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
    color-scheme: dark;
}

/*
 * Motion is a preference, not a flourish. Everything animated here is a hint
 * about what just changed, so it degrades to instant rather than disappearing.
 */
@media (prefers-reduced-motion: reduce) {
    :root { --motion: 0s; }

    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

* { box-sizing: border-box; }

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

body {
    background: var(--bg);
    color: var(--ink);
    font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    padding-bottom: env(safe-area-inset-bottom);
}

a { color: var(--brand-dark); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; line-height: 1.25; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }
p { margin: 0 0 10px; }

/* ---------------------------------------------------------------- shell */

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

/*
 * Three bands: brand, a scrolling link list, and the account block. Only the
 * middle one scrolls, so with a long admin menu the profile and sign-out stay
 * on screen instead of disappearing off the bottom.
 */
.sidebar {
    width: var(--nav-w);
    flex: 0 0 var(--nav-w);
    background: var(--surface);
    border-right: 1px solid var(--line);
    padding: 18px 14px;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
}

.sidebar .brand { flex: 0 0 auto; }

.sidebar-nav {
    flex: 1 1 auto;
    min-height: 0;              /* lets the list actually scroll inside flex */
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    /* Bleed the scrollbar into the padding so rows keep their full width. */
    margin: 0 -6px;
    padding: 0 6px;
    scrollbar-width: thin;
}
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 3px; }
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); }

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px 18px;
    font-weight: 700;
    font-size: 18px;
    color: var(--ink);
}
.brand:hover { text-decoration: none; }
.brand-mark {
    width: 32px; height: 32px; border-radius: 10px;
    background: linear-gradient(135deg, var(--brand), #34c79a);
    color: #fff; display: grid; place-items: center;
    font-size: 15px; font-weight: 700;
}

.nav-link {
    display: flex; align-items: center; gap: 11px;
    padding: 9px 11px; border-radius: var(--radius-sm);
    color: var(--ink-2); font-weight: 500;
}
.nav-link:hover { background: var(--hover); text-decoration: none; }
.nav-link.active { background: var(--brand-soft); color: var(--brand-dark); font-weight: 600; }
.nav-link .icon { flex: 0 0 auto; }
.nav-badge {
    margin-left: auto; background: var(--danger); color: #fff;
    font-size: 11px; font-weight: 700; min-width: 19px; height: 19px;
    border-radius: 10px; display: grid; place-items: center; padding: 0 5px;
}

/*
 * Group headings are real headings, so a screen reader announces which part of
 * the menu it is in. That means clearing the margins a browser gives an h2 and
 * setting the size here rather than inheriting a document-level one.
 */
.nav-section {
    margin: 0;
    font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
    color: var(--muted); font-weight: 600; padding: 14px 11px 5px;
}

/* A hairline does the separating, so the headings can stay quiet. */
.nav-group + .nav-group { border-top: 1px solid var(--line); margin-top: 6px; }

.sidebar-footer {
    flex: 0 0 auto;
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
    background: var(--surface);
}

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: 12px 20px;
    display: flex; align-items: center; gap: 12px;
    position: sticky; top: 0; z-index: 20;
}
.topbar .spacer { flex: 1; }

/* Language, theme and the bell: one unit, so they wrap as one. */
.topbar-utils { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }

.content { padding: 20px; max-width: 1180px; width: 100%; }

/* ------------------------------------------------------------ elements */

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}
.card-pad { padding: 16px; }
.card-head {
    padding: 14px 16px; border-bottom: 1px solid var(--line);
    display: flex; align-items: center; gap: 10px;
}
.card-head h2 { flex: 1; }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

.row { display: flex; align-items: center; gap: 10px; }
.row-wrap { flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: 14px; }
.spacer { flex: 1; }

.stat { padding: 15px 16px; }
.stat .label { color: var(--muted); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.stat .value { font-size: 27px; font-weight: 700; margin-top: 4px; letter-spacing: -.02em; }
.stat .hint { color: var(--muted); font-size: 12px; }

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    padding: 9px 15px; border-radius: var(--radius-sm);
    border: 1px solid var(--line); background: var(--surface); color: var(--ink);
    font: inherit; font-weight: 600; font-size: 14px; cursor: pointer;
    transition: background .12s, border-color .12s;
}
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
.btn-danger { color: var(--danger); border-color: var(--danger-line); background: var(--surface); }
.btn-danger:hover { background: var(--danger-soft); }
.btn-sm { padding: 6px 11px; font-size: 13px; }
.btn-block { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.badge {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 999px;
    font-size: 12px; font-weight: 600;
    background: var(--hover); color: var(--ink-2);
}
.badge-present { background: var(--brand-soft); color: var(--brand-dark); }
.badge-out { background: var(--info-soft); color: var(--info-ink); }
.badge-absent { background: var(--danger-soft); color: var(--danger-ink); }
.badge-late { background: var(--warn-soft); color: var(--warn-ink); }

.avatar {
    width: 40px; height: 40px; border-radius: 50%;
    background: var(--brand-soft); color: var(--brand-dark);
    display: grid; place-items: center; font-weight: 700; font-size: 14px;
    flex: 0 0 auto; overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-lg { width: 64px; height: 64px; font-size: 21px; }
.avatar-sm { width: 30px; height: 30px; font-size: 11px; }

/* ------------------------------------------------------- accessibility */

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

.skip-link {
    position: absolute; left: 8px; top: -60px; z-index: 300;
    background: var(--brand); color: #fff; padding: 10px 16px;
    border-radius: var(--radius-sm); font-weight: 600;
    transition: top .12s;
}
.skip-link:focus { top: 8px; text-decoration: none; }

:focus-visible {
    outline: 2px solid var(--brand-dark);
    outline-offset: 2px;
}

/* ------------------------------------------------------------ lightbox */

.lightbox {
    position: fixed; inset: 0; z-index: 250;
    background: rgba(15, 23, 42, .92);
    display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 14px; padding: 24px;
}
.lightbox[hidden] { display: none; }
.lightbox img {
    max-width: min(1100px, 96vw); max-height: 82vh;
    object-fit: contain; border-radius: var(--radius-sm);
}
.lightbox-caption { color: var(--line); font-size: 14px; margin: 0; text-align: center; }
.lightbox-close {
    position: absolute; top: 16px; right: 16px;
    width: 42px; height: 42px; border-radius: 50%;
    background: rgba(255, 255, 255, .12); color: #fff;
    border: 0; cursor: pointer; display: grid; place-items: center;
}
.lightbox-close:hover { background: rgba(255, 255, 255, .22); }

button.photo-tile { border: 0; padding: 0; cursor: pointer; font: inherit; }

/* The snapshot taken at the door when a child was collected. */
.pickup-shot {
    width: 42px; height: 42px; padding: 0; flex: 0 0 auto;
    border: 1px solid var(--line); border-radius: 8px;
    overflow: hidden; cursor: pointer; background: var(--line);
}
.pickup-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

.file-chip {
    display: inline-flex; align-items: center; gap: 7px; max-width: 240px;
    margin-top: 6px; padding: 7px 11px; border-radius: 9px;
    background: rgba(255, 255, 255, .16); color: inherit;
    font-size: 13px; font-weight: 550;
}
.bubble:not(.mine) .file-chip,
.bubble-row:not(.mine) .file-chip { background: var(--hover); color: var(--ink-2); }
.file-chip:hover { text-decoration: none; opacity: .88; }

/* Phosphor sprite icons. They inherit colour from the parent via currentColor. */
.icon { display: block; fill: currentColor; }
.badge .icon, .btn .icon, .list-item .sub .icon { display: inline-block; vertical-align: -3px; }

.muted { color: var(--muted); }
.small { font-size: 13px; }
.tiny { font-size: 12px; }
.strong { font-weight: 650; }
.center { text-align: center; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.empty {
    padding: 38px 20px; text-align: center; color: var(--muted);
}
.empty .icon { display: block; margin: 0 auto 10px; color: var(--line-strong); }

.flash {
    background: var(--brand-soft); color: var(--brand-dark);
    border: 1px solid var(--brand-line); border-radius: var(--radius-sm);
    padding: 10px 14px; margin-bottom: 16px; font-weight: 550;
}

.alert-error {
    background: var(--danger-soft); color: var(--danger-ink);
    border: 1px solid var(--danger-line); border-radius: var(--radius-sm);
    padding: 10px 14px; margin-bottom: 14px;
}
.alert-error ul { margin: 0; padding-left: 18px; }

/*
 * A settings row is a whole label, so the text is part of the hit target
 * rather than leaving a checkbox as the only thing worth aiming at.
 */
.pref-row {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 13px 2px; border-bottom: 1px solid var(--line);
    cursor: pointer;
}
.pref-row:last-of-type { border-bottom: 0; }
.pref-row input { margin-top: 3px; flex: 0 0 auto; width: 17px; height: 17px; }
.pref-row .body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pref-row .title { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.pref-row .sub { color: var(--muted); font-size: 13px; }
.pref-row[aria-disabled="true"] { cursor: default; }
.pref-row[aria-disabled="true"] .title { color: var(--ink-2); }

/*
 * overflow-y is pinned rather than left alone. Setting only overflow-x makes
 * the other axis compute to auto, so the strip offered a vertical scrollbar
 * for the one pixel the active tab used to hang below it.
 */
.tabs {
    display: flex; gap: 4px; margin-bottom: 18px;
    border-bottom: 1px solid var(--line);
    overflow-x: auto; overflow-y: hidden;
}
.tab {
    display: flex; align-items: center; gap: 7px;
    padding: 10px 14px; white-space: nowrap;
    color: var(--muted); font-weight: 600; font-size: 14px;
}
.tab:hover { color: var(--ink-2); text-decoration: none; }

/* The underline is drawn inside the tab. A border pulled down over the
   strip's own line is what created the overflow in the first place. */
.tab.active { color: var(--brand-dark); box-shadow: inset 0 -2px 0 0 var(--brand); }

/* Separates two halves of one tab without pretending to be a page heading. */
.section-rule {
    font-size: 14px; font-weight: 650; color: var(--ink-2);
    padding-top: 22px; margin: 0 0 12px;
    border-top: 1px solid var(--line);
}

/* One child inside an application under review. */
.child-review {
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: 14px 16px; margin-bottom: 10px; background: var(--surface-2);
}
.child-review:last-child { margin-bottom: 0; }

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

label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 5px; }

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], input[type=search], input[type=tel], input[type=color],
select, textarea {
    width: 100%; padding: 9px 11px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink); font: inherit;
}
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(31, 157, 118, .13);
}
input[type=color] { padding: 3px; height: 38px; }
textarea { resize: vertical; min-height: 84px; }

.field { margin-bottom: 14px; }
.field .error { color: var(--danger); font-size: 12px; margin-top: 4px; }

.checklist {
    max-height: 220px; overflow-y: auto;
    border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px;
}
.check {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 8px; border-radius: 7px; cursor: pointer;
    font-weight: 500; color: var(--ink-2); margin: 0;
}
.check:hover { background: var(--surface-2); }
.check input { width: auto; margin: 0; }

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

.list { list-style: none; margin: 0; padding: 0; }
.list-item {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 16px; border-bottom: 1px solid var(--line);
    color: inherit;
}
.list-item:last-child { border-bottom: 0; }
a.list-item:hover { background: var(--surface-2); text-decoration: none; }
.list-item .body { flex: 1; min-width: 0; }
.list-item .title { font-weight: 600; }
.list-item .sub { color: var(--muted); font-size: 13px; }

/*
 * A table is only ever as narrow as its content allows. width:100% below is a
 * hint that the intrinsic minimum overrides, so five columns of room, age
 * group, present, educators and ratio simply do not fit a phone — and an
 * unwrapped table does not clip or scroll, it widens everything containing it.
 * The dashboard pushed its own card, the page and the header off to the left,
 * so the first thing on screen was the middle of the layout.
 *
 * Scrolling the table inside its own box leaves the rest of the page alone.
 * Same treatment .tabs and .canned already get.
 */
.table-wrap { overflow-x: auto; }

.table { width: 100%; border-collapse: collapse; }
.table th, .table td { padding: 11px 16px; text-align: left; border-bottom: 1px solid var(--line); }
.table th { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.table tbody tr:last-child td { border-bottom: 0; }

/* -------------------------------------------------------------- photos */

.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.photo-tile {
    position: relative; aspect-ratio: 1; border-radius: var(--radius-sm);
    overflow: hidden; background: var(--line); display: block;
}
.photo-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-tile .cap {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 16px 8px 6px; color: #fff; font-size: 12px;
    background: linear-gradient(transparent, rgba(0, 0, 0, .62));
}

/* ---------------------------------------------------------------- chat */

/* Positioned so the jump-to-latest button anchors to the thread rather than
   to the viewport. */
.chat { display: flex; flex-direction: column; height: calc(100vh - 62px); position: relative; }
.chat-head {
    padding: 12px 16px; border-bottom: 1px solid var(--line);
    background: var(--surface); display: flex; align-items: center; gap: 11px;
}
.chat-body {
    flex: 1; overflow-y: auto; padding: 18px 16px;
    display: flex; flex-direction: column; gap: 10px;
    background: var(--bg);
}
.bubble-row { display: flex; gap: 9px; align-items: flex-end; max-width: 78%; }
.bubble-row.mine { align-self: flex-end; flex-direction: row-reverse; }
.bubble {
    background: var(--surface); border: 1px solid var(--line);
    padding: 9px 13px; border-radius: 16px 16px 16px 4px;
    box-shadow: var(--shadow-sm); word-break: break-word;
}
.mine .bubble {
    background: var(--brand); border-color: var(--brand); color: #fff;
    border-radius: 16px 16px 4px 16px;
}
.bubble .who { font-size: 12px; font-weight: 700; color: var(--brand-dark); margin-bottom: 2px; }
.bubble .when { font-size: 11px; color: var(--muted); margin-top: 3px; text-align: right; }
.mine .bubble .when { color: rgba(255, 255, 255, .78); }
.bubble img { max-width: 100%; border-radius: 9px; margin-top: 6px; display: block; }
.day-sep { text-align: center; font-size: 12px; color: var(--muted); margin: 6px 0; }

.chat-compose {
    border-top: 1px solid var(--line); background: var(--surface);
    padding: 10px 12px; display: flex; gap: 9px; align-items: flex-end;
}
.chat-compose textarea {
    flex: 1; min-height: 40px; max-height: 130px; resize: none;
    border-radius: 20px; padding: 10px 15px;
}
.icon-btn {
    width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto;
    display: grid; place-items: center; cursor: pointer;
    border: 1px solid var(--line); background: var(--surface);
    color: var(--ink-2);
}
.icon-btn:hover { background: var(--surface-2); }
.icon-btn.send { background: var(--brand); border-color: var(--brand); color: #fff; }

.conn-dot {
    width: 8px; height: 8px; border-radius: 50%; background: var(--line-strong);
    flex: 0 0 auto;
}
.conn-dot.live { background: var(--brand); box-shadow: 0 0 0 3px rgba(31, 157, 118, .18); }

.typing-line {
    min-height: 18px; padding: 0 16px 2px;
    font-size: 12px; color: var(--muted); font-style: italic;
}

.offline-line {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 16px; font-size: 13px;
    background: var(--warn-soft); color: var(--warn-ink);
}
.offline-line[hidden] { display: none; }

.bubble.tombstone { background: var(--hover); border-style: dashed; color: var(--muted); }
.mine .bubble.tombstone { background: var(--hover); border-color: var(--line); }

.msg-tools { display: none; margin-inline-start: 6px; }
.bubble:hover .msg-tools, .msg-tools:focus-within { display: inline-flex; gap: 4px; }
.msg-tools button {
    background: none; border: 0; padding: 0 2px; cursor: pointer;
    color: inherit; opacity: .75;
}
.msg-tools button:hover { opacity: 1; }

/* ------------------------------------------------------- notifications */

.bell { position: relative; }
.bell .dot {
    position: absolute; top: 2px; right: 2px;
    min-width: 16px; height: 16px; padding: 0 4px;
    background: var(--danger); color: #fff; border-radius: 8px;
    font-size: 10px; font-weight: 700; display: grid; place-items: center;
}

.toast-host {
    position: fixed; right: 16px; bottom: 16px; z-index: 200;
    display: flex; flex-direction: column; gap: 8px; max-width: 330px;
}
.toast {
    background: var(--toast-bg); color: var(--toast-ink); padding: 11px 14px;
    border-radius: var(--radius-sm); box-shadow: var(--shadow);
    font-size: 14px; animation: toast-in .18s ease-out;
}
.toast .t { font-weight: 700; margin-bottom: 2px; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* ------------------------------------------------------------ tab bar */

.tabbar { display: none; }

/* ---------------------------------------------------------------- auth */

.auth-wrap {
    min-height: 100vh; display: grid; place-items: center; padding: 24px;
    background: linear-gradient(160deg, var(--wash-1), var(--wash-2) 55%);
}
.auth-card { width: 100%; max-width: 400px; }
.auth-card .card-pad { padding: 26px; }

/* -------------------------------------------------------------- mobile */

@media (max-width: 899px) {
    .sidebar { display: none; }

    /*
     * 16px each side across five columns is 160px spent on padding before a
     * single word is drawn. Tighter here so most tables fit outright and the
     * scroll above is a fallback rather than the usual experience.
     */
    .table th, .table td { padding: 11px 10px; }

    /*
     * The full menu as a drawer. The tab bar along the bottom is the shortcut
     * to the five places people go constantly; this is how they reach the
     * other nine.
     */
    body.nav-open .sidebar {
        display: flex;
        position: fixed; top: 0; bottom: 0; left: 0;
        width: min(290px, 84vw); height: 100dvh;
        z-index: 60; box-shadow: var(--shadow);
    }
    body.nav-open::before {
        content: ''; position: fixed; inset: 0; z-index: 55;
        background: rgba(15, 23, 42, .5);
    }

    /* The rail is a wide-screen idea; a narrow screen gets the drawer or
       nothing, never a strip of unlabelled icons over the content. */
    body.nav-rail .sidebar { width: min(290px, 84vw); padding: 18px 14px; }
    body.nav-rail .nav-link,
    body.nav-rail .brand,
    body.nav-rail .sidebar-footer .btn { font-size: inherit; gap: 11px; justify-content: flex-start; }
    body.nav-rail .nav-section,
    body.nav-rail .sidebar-footer .row > div { display: revert; }
    body.nav-rail .nav-badge { position: static; margin-left: auto; }

    .content { padding: 14px; padding-bottom: calc(var(--tabbar-h) + 22px); }

    /*
     * The row carries a title, whatever action the page offers, the language
     * switch and two icon buttons. A flex item will not shrink below its own
     * content unless told to, and nothing here wraps, so on a phone this row
     * set a floor under the width of the whole page: the header, the cards and
     * everything else anchored to the viewport slid off to the left, and the
     * page opened somewhere in its own middle.
     *
     * Wrapping costs a second row only when the first will not hold, and
     * nothing has to be hidden to make it fit.
     */
    /*
     * Deliberately nowrap, after wrapping turned out to be the wrong lever.
     *
     * A wrapping flex row does not shrink its items — it moves whichever one
     * will not fit onto a new line — so one long title was enough to send the
     * language switch, the theme toggle and the bell down a row and spend 40px
     * of a small screen on nothing. Everything here except the heading is a
     * fixed, small control, so holding the line and letting the heading give
     * way is both safe and what a phone's own app bars do.
     */
    .topbar { padding: 10px 12px; flex-wrap: nowrap; gap: 8px; }

    /*
     * The one thing on this row that can afford to lose a few characters.
     * "Incident reports" becomes "Incident report…" at 412px rather than
     * pushing everything else off the end of the row.
     */
    .topbar h1 {
        font-size: 18px; min-width: 0;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }

    /* The word stays — it is the one control a person who cannot read the page
       has to be able to find — but it does not need to sit in so much air. */
    .topbar .lang-btn { padding: 0 9px; }

    /*
     * .spacer already pushes these to the right edge, so no auto margin: an
     * auto margin takes free space before flex-grow does, which would strand
     * the page's action next to the title instead of beside these.
     *
     * The icon buttons keep their size. They are already under the 44px a
     * thumb wants, and shrinking a target to win a layout argument is the
     * wrong way round.
     */
    .topbar-utils { gap: 8px; flex: 0 0 auto; }

    /*
     * The page's action collapses to its icon, which is what buys the single
     * row: "Add medication" costs about 150px on a phone and the header has
     * nowhere to spend it.
     *
     * Collapsed with font-size rather than display, the same way the nav rail
     * does it, because the label is a bare text node and hiding it outright
     * would take the button's accessible name with it. Screen readers still
     * read it; the SVG carries its own width, so it survives.
     *
     * :has() guards the case this cannot help — a button with no icon would
     * collapse to an empty square, so it keeps its words and wraps instead.
     */
    .topbar .btn:has(.icon) { font-size: 0; gap: 0; padding-left: 9px; padding-right: 9px; }
    .chat { height: calc(100vh - 56px - var(--tabbar-h)); }
    .chat-body { padding: 14px 12px; }
    .bubble-row { max-width: 88%; }

    .tabbar {
        display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
        background: var(--surface); border-top: 1px solid var(--line);
        height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
        padding-bottom: env(safe-area-inset-bottom);
    }
    .tabbar a {
        flex: 1; display: flex; flex-direction: column; align-items: center;
        justify-content: center; gap: 2px; color: var(--muted);
        font-size: 11px; font-weight: 600; position: relative;
    }
    .tabbar a:hover { text-decoration: none; }
    .tabbar a.active { color: var(--brand-dark); }
    .tabbar .nav-badge {
        position: absolute; top: 5px; left: 50%; margin-left: 4px;
    }
    .chat-page .tabbar { display: none; }
    .chat-page .chat { height: calc(100vh - 56px); }
}

/* ------------------------------------------------------- shell additions */

/*
 * The connection banner. Pinned rather than inline: losing the network while
 * halfway down a form is exactly when a message at the top of the page goes
 * unread.
 */
.offline-banner {
    position: fixed; left: 50%; transform: translateX(-50%);
    bottom: calc(env(safe-area-inset-bottom) + 16px);
    z-index: 250;
    display: none; align-items: center; gap: 9px;
    background: var(--warn-soft); color: var(--warn-ink);
    border: 1px solid var(--warn-ink);
    border-radius: 999px; padding: 9px 16px;
    font-size: 13px; font-weight: 650;
    box-shadow: var(--shadow);
}
body.is-offline .offline-banner { display: inline-flex; }

@media (max-width: 900px) {
    .offline-banner { bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 12px); }
}

/*
 * A placeholder that admits it is a placeholder. Sized like the thing it
 * stands in for so the page does not jump when the real content lands.
 */
.skeleton {
    background: var(--skeleton);
    border-radius: var(--radius-sm);
    animation: skeleton-pulse 1.3s ease-in-out infinite;
}
.skeleton-line { height: 12px; margin-bottom: 8px; }
.skeleton-line.short { width: 45%; }
.skeleton-line.medium { width: 70%; }
.skeleton-avatar { width: 40px; height: 40px; border-radius: 50%; }
@keyframes skeleton-pulse { 50% { opacity: .55; } }

/*
 * The sidebar collapsed to icons. Labels are hidden rather than removed so
 * the accessible name survives, and the title attribute gives a hover hint
 * to anyone who has forgotten which glyph is which.
 */
body.nav-rail .sidebar { width: var(--nav-w-rail); flex: 0 0 var(--nav-w-rail); padding: 18px 8px; }

/*
 * Labels are bare text nodes rather than elements, so they are collapsed with
 * font-size rather than display. The icons are SVGs with their own width and
 * the badge sets its size back, so both survive; screen readers still read the
 * text, which is the point of collapsing it rather than deleting it.
 */
body.nav-rail .nav-link,
body.nav-rail .brand,
body.nav-rail .sidebar-footer .btn { font-size: 0; gap: 0; justify-content: center; }
body.nav-rail .nav-link { padding: 10px 0; position: relative; }
body.nav-rail .brand { padding: 4px 0 18px; }
body.nav-rail .nav-section { display: none; }
body.nav-rail .sidebar-footer .row > div { display: none; }
body.nav-rail .sidebar-footer .row { justify-content: center; }
body.nav-rail .nav-badge {
    font-size: 11px; margin: 0;
    position: absolute; top: 4px; right: 6px;
}

/*
 * Always available. On a wide screen it collapses the sidebar to a rail; on a
 * narrow one it opens the sidebar as a drawer, because the tab bar carries
 * five destinations and the menu carries fourteen. Hiding the sidebar without
 * offering it back put most of the app out of reach on a small window.
 */
.nav-toggle {
    background: none; border: 0; cursor: pointer; color: var(--muted);
    padding: 6px; border-radius: var(--radius-sm);
    display: inline-flex; align-items: center;
}
.nav-toggle:hover { background: var(--hover); color: var(--ink); }

/* Dismissible, because a confirmation you cannot get rid of becomes furniture. */
.toast .toast-close {
    background: none; border: 0; color: inherit; opacity: .65;
    cursor: pointer; padding: 0 0 0 10px; font-size: 15px; line-height: 1;
}
.toast .toast-close:hover { opacity: 1; }
.toast { display: flex; align-items: flex-start; }
.toast .toast-body { flex: 1; min-width: 0; }

/* ------------------------------------------------------- search overlay */

.omni-open {
    display: none; align-items: center; gap: 8px;
    background: var(--surface-2); border: 1px solid var(--line);
    border-radius: 999px; padding: 6px 10px 6px 12px;
    color: var(--muted); font: inherit; font-size: 13px; cursor: pointer;
    min-width: 210px; text-align: left;
}
.omni-open:hover { border-color: var(--line-strong); color: var(--ink-2); }
.omni-open span { flex: 1; }
@media (min-width: 760px) { .omni-open { display: inline-flex; } }

kbd {
    font: inherit; font-size: 11px; font-weight: 600;
    background: var(--surface); border: 1px solid var(--line);
    border-bottom-width: 2px; border-radius: 5px;
    padding: 1px 5px; color: var(--muted); margin-left: 3px;
}

.omni {
    position: fixed; inset: 0; z-index: 400;
    background: rgba(15, 23, 42, .45);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 12vh 16px 16px;
}
.omni[hidden] { display: none; }

.omni-panel {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow);
    width: 100%; max-width: 560px; overflow: hidden;
}

.omni-field {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 15px; border-bottom: 1px solid var(--line);
    color: var(--muted);
}
.omni-field input {
    flex: 1; border: 0; background: none; padding: 0;
    font: inherit; font-size: 16px; color: var(--ink); outline: none;
}
.omni-close { background: none; border: 0; color: var(--muted); cursor: pointer; padding: 2px; }
.omni-close:hover { color: var(--ink); }

.omni-results { max-height: 52vh; overflow-y: auto; }
.omni-group-heading {
    font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
    color: var(--muted); font-weight: 700; padding: 12px 15px 5px;
}
.omni-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 15px; color: var(--ink); cursor: pointer;
}
.omni-item:hover, .omni-item.is-active { background: var(--hover); text-decoration: none; }
.omni-item .label { flex: 1; font-weight: 550; }
.omni-item .hint { color: var(--muted); font-size: 12px; }
.omni-empty { padding: 24px 15px; text-align: center; color: var(--muted); font-size: 14px; }

.omni-foot {
    display: flex; gap: 16px; padding: 9px 15px;
    border-top: 1px solid var(--line); background: var(--surface-2);
    color: var(--muted); font-size: 12px;
}
@media (max-width: 560px) { .omni-foot { display: none; } }

.shortcut-list { padding: 6px 0; }
.shortcut-row {
    display: flex; justify-content: space-between; align-items: center;
    padding: 9px 15px; font-size: 14px;
}
.shortcut-row + .shortcut-row { border-top: 1px solid var(--line); }

/* ------------------------------------------------------------ breadcrumb */

.crumbs {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-size: 13px; color: var(--muted); margin-bottom: 14px;
}
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--ink-2); }
.crumbs .sep { opacity: .5; }
.crumbs .here { color: var(--ink-2); font-weight: 600; }

/* Recently viewed, offered where somebody is already looking for a child. */
.recents { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.recent-chip {
    display: inline-flex; align-items: center; gap: 7px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 999px; padding: 5px 12px 5px 6px;
    font-size: 13px; font-weight: 550; color: var(--ink-2);
}
.recent-chip:hover { border-color: var(--line-strong); text-decoration: none; }

/* ---------------------------------------------------- messaging extras */

/* Where reading left off. Loud enough to find by scrolling, quiet enough not
   to look like an error. */
.unread-sep {
    display: flex; align-items: center; gap: 10px;
    margin: 14px 0 6px; color: var(--danger);
    font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em;
}
.unread-sep::before, .unread-sep::after {
    content: ''; flex: 1; height: 1px; background: var(--danger-line);
}

.jump-latest {
    position: absolute; left: 50%; transform: translateX(-50%);
    bottom: 92px; z-index: 5;
    display: inline-flex; align-items: center; gap: 7px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 999px; padding: 7px 14px;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--ink-2);
    box-shadow: var(--shadow); cursor: pointer;
}
.jump-latest[hidden] { display: none; }
.jump-latest:hover { border-color: var(--line-strong); }

.canned {
    display: flex; gap: 6px; overflow-x: auto; padding: 8px 14px 0;
    scrollbar-width: thin;
}
.canned-chip {
    flex: 0 0 auto; white-space: nowrap;
    background: var(--surface-2); border: 1px solid var(--line);
    border-radius: 999px; padding: 5px 12px;
    font: inherit; font-size: 13px; color: var(--ink-2); cursor: pointer;
}
.canned-chip:hover { background: var(--hover); border-color: var(--line-strong); }

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

/* Severity is the first thing you need from an incident list and it was
   spelled out in prose in the middle of a row. */
.sev { border-left: 3px solid transparent; }
.sev-minor { border-left-color: var(--brand); }
.sev-moderate { border-left-color: var(--warn-ink); }
.sev-serious, .sev-major { border-left-color: var(--danger); }

.due-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; }
.due-row + .due-row { border-top: 1px solid var(--line); }
.due-time { font-variant-numeric: tabular-nums; font-weight: 700; }

/* ------------------------------------------------------------- printing */

/*
 * A daily report gets printed for the parent who wants paper, and for the
 * folder an inspector asks for. Everything that is navigation on screen is
 * noise on a page.
 */
@media print {
    .sidebar, .topbar, .tabbar, .toast-host, .omni, .offline-banner,
    .crumbs, .jump-latest, .canned, .chat-compose, .no-print { display: none !important; }

    .app, .main, .content { display: block; max-width: none; padding: 0; }
    .card { border: 1px solid #ddd; box-shadow: none; break-inside: avoid; }
    body { background: #fff; color: #000; }
    a { color: #000; text-decoration: none; }

    /* A link that says "click here" is useless on paper, so say where it goes. */
    .content a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 11px; }

    .print-only { display: block !important; }
}
.print-only { display: none; }

/* --------------------------------------------------------- small extras */

.day-heading {
    display: flex; align-items: baseline; gap: 10px;
    font-size: 14px; font-weight: 700; color: var(--ink-2);
    padding: 14px 0 10px; border-top: 1px solid var(--line);
    margin-top: 6px;
}
.day-heading:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.day-heading .muted { font-weight: 500; font-size: 13px; }

/* A button that reads as a link, for actions inside a label. */
.linkish {
    background: none; border: 0; padding: 0 0 0 8px;
    color: var(--brand-dark); font: inherit; font-size: 12px;
    font-weight: 600; cursor: pointer; text-decoration: underline;
}

/* The timeline on a child, one column of everything in date order. */
.timeline { position: relative; padding-left: 22px; }
.timeline::before {
    content: ''; position: absolute; left: 6px; top: 4px; bottom: 4px;
    width: 2px; background: var(--line);
}
.tl-item { position: relative; padding: 0 0 16px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
    content: ''; position: absolute; left: -20px; top: 5px;
    width: 10px; height: 10px; border-radius: 50%;
    background: var(--surface); border: 2px solid var(--line-strong);
}
.tl-item.is-incident::before { border-color: var(--danger); }
.tl-item.is-attendance::before { border-color: var(--brand); }
.tl-item.is-medication::before { border-color: var(--info-ink); }
.tl-when { font-size: 12px; color: var(--muted); }

/* ------------------------------------------------------ attendance pattern */

/*
 * Six weeks of days as a row of squares. Small on purpose: the shape is the
 * information, and a legible date on each one would bury it.
 */
.pattern { display: flex; flex-wrap: wrap; gap: 3px; }
.pattern-key { display: flex; align-items: center; gap: 5px; }
.pat {
    width: 13px; height: 13px; border-radius: 3px;
    background: var(--hover); flex: 0 0 auto;
}
.pat-present { background: var(--brand); }
.pat-late { background: var(--warn-ink); }
.pat-absent, .pat-excused { background: var(--danger-line); }
.pat-none { background: var(--hover); }
.pat-weekend { background: transparent; border: 1px dashed var(--line); }

/* The retrospective correction, folded away until it is wanted. */
.correct-times { margin-top: 6px; }
.correct-times summary {
    cursor: pointer; font-size: 12px; color: var(--muted);
    list-style: none; display: inline-flex; align-items: center; gap: 4px;
}
.correct-times summary::-webkit-details-marker { display: none; }
.correct-times summary::before { content: '+'; font-weight: 700; }
.correct-times[open] summary::before { content: '−'; }
.correct-times summary:hover { color: var(--ink-2); }
.correct-times input[type=time], .correct-times input[type=text] { padding: 5px 8px; font-size: 13px; }

/*
 * An unread row is tinted with the brand rather than with a light grey. The
 * grey was written as a literal, so in dark mode it painted a near-white strip
 * under near-white text: 1.13 to 1, where 4.5 is the floor for body text.
 */
.list-item.is-unread { background: var(--brand-soft); }
a.list-item.is-unread:hover { background: var(--brand-soft); filter: brightness(1.06); }

/* Muted grey against the tint measured 4.3 to 1, just under the 4.5 floor for
   text this size. On an unread row the message is the point anyway. */
.list-item.is-unread .sub { color: var(--ink-2); }

/* Inline code and tokens: a surface, so it follows the theme. */
code {
    background: var(--surface-2); color: var(--ink);
    border: 1px solid var(--line); border-radius: 6px;
}

/* ------------------------------------------------------------ file field */

/*
 * The native input is moved out of sight rather than hidden, so it keeps its
 * place in the tab order and the surrounding label can show the focus ring on
 * its behalf. display:none would take it out of the tab order entirely and
 * leave a keyboard user with no way to reach it.
 */
.dropzone {
    position: relative; display: block; cursor: pointer;
    border: 1px dashed var(--line-strong); border-radius: var(--radius-sm);
    background-color: var(--surface-2); padding: 16px;
    transition: border-color var(--motion), background-color var(--motion);
}
.dropzone:hover { border-color: var(--brand); background-color: var(--hover); }
.dropzone:focus-within { outline: 2px solid var(--brand-dark); outline-offset: 2px; }

.dropzone-input {
    position: absolute; width: 1px; height: 1px;
    opacity: 0; pointer-events: none;
}

.dropzone-idle, .dropzone-chosen { display: flex; align-items: center; gap: 12px; }
.dropzone-chosen[hidden], .dropzone-idle[hidden] { display: none; }

.dropzone-icon {
    width: 38px; height: 38px; border-radius: 50%; flex: 0 0 auto;
    background: var(--brand-soft); color: var(--brand-dark);
    display: grid; place-items: center;
}
.dropzone-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dropzone-text strong { font-weight: 600; font-size: 14px; }
.dropzone-text .muted { font-size: 12px; }
.dropzone-text strong[data-file-name] {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* A file is chosen: the box stops looking like an invitation. */
.dropzone.has-file {
    border-style: solid; border-color: var(--brand);
    background-color: var(--brand-soft);
}
.dropzone.has-file .dropzone-icon { background-color: var(--surface); }

/* Dragging over it. Only ever set by script, so it cannot get stuck on for
   anyone whose browser never fires the leave event. */
.dropzone.is-dragging {
    border-color: var(--brand); background: var(--brand-soft);
    border-style: solid;
}

.dropzone-clear {
    margin-left: auto; flex: 0 0 auto;
    background: none; border: 0; cursor: pointer;
    color: var(--muted); padding: 6px; border-radius: 50%;
    display: inline-flex;
}
.dropzone-clear:hover { background: var(--surface); color: var(--danger); }

/*
 * Thumbnails of what is about to be shared. These are photographs of other
 * people's children, and the moment to notice the wrong one is before it
 * reaches their parents.
 */
.dropzone-previews {
    display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px;
}
.dropzone-previews[hidden] { display: none; }
.dropzone-thumb {
    width: 62px; height: 62px; border-radius: var(--radius-sm);
    overflow: hidden; border: 1px solid var(--line); background: var(--surface-2);
    flex: 0 0 auto;
}
.dropzone-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* -------------------------------------------------------- checklist filter */

.checklist-filter {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; margin-bottom: 8px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--surface-2); color: var(--muted);
}
.checklist-filter:focus-within { border-color: var(--brand); }
.checklist-filter input {
    flex: 1; border: 0; background: none; padding: 0;
    font: inherit; color: var(--ink); min-width: 0;
}
.checklist-filter input:focus { outline: none; }
.checklist-filter [data-checklist-count] { white-space: nowrap; }

/*
 * A row kept on screen only because it is ticked, while the filter would
 * otherwise have hidden it. Marked so it does not look like a match.
 */
.check.is-kept {
    background: var(--brand-soft);
    border-radius: var(--radius-sm);
}

/* ---------------------------------------------------------- language pick */

.lang-switch { display: inline-flex; align-items: center; gap: 6px; }
.lang-switch select {
    padding: 6px 10px; font-size: 13px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink-2);
}
.lang-switch.is-compact select {
    border-color: transparent; background: none; padding: 4px 6px;
}
.lang-switch.is-compact select:hover { background: var(--hover); }

/*
 * The language toggle. Sits with the icon buttons in the top bar and matches
 * their height, but carries a word: a globe would have to be guessed at, and
 * the person who most needs this control is the one who cannot read a tooltip.
 */
.lang-toggle { display: inline-flex; }
.lang-btn {
    display: inline-flex; align-items: center; justify-content: center;
    height: 36px; padding: 0 12px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink-2);
    font: inherit; font-size: 13px; font-weight: 650; cursor: pointer;
    white-space: nowrap;
    transition: background var(--motion), border-color var(--motion);
}
.lang-btn:hover { background: var(--hover); color: var(--ink); border-color: var(--line-strong); }
