/* =========================================================================
   TicketSystem — design system
   -------------------------------------------------------------------------
   A calm, modern product UI: light chrome, soft geometry, one confident
   accent, and colour reserved for status. No gradients.
   Loaded last, so it wins over the compiled Tailwind build.
   ========================================================================= */

/* ---------- 1. tokens ---------- */

:root {
    /* neutrals */
    --bg:        #F6F7FB;  /* page ground */
    --surface:   #FFFFFF;  /* cards, bars */
    --surface-2: #F3F4F8;  /* subtle fills, hover */
    --line:      #E5E7EF;  /* hairlines */
    --line-2:    #D3D7E3;  /* stronger edges */

    --text:   #12162A;  /* headings, primary text */
    --text-2: #545C73;  /* secondary */
    --text-3: #808AA3;  /* meta, placeholders */

    /* brand */
    --brand:      #5A54E8;
    --brand-deep: #443DD1;
    --brand-soft: #EEEDFD;
    --brand-ring: rgba(90, 84, 232, .28);

    /* status */
    --ok:        #0E9F8A;
    --ok-soft:   #E2F6F2;
    --warn:      #C97A0A;
    --warn-soft: #FDF1DF;
    --bad:       #DC3B47;
    --bad-soft:  #FDEAEC;

    /* type */
    --display: "Readex Pro", "Segoe UI", system-ui, sans-serif;
    --ui: "Readex Pro", "Segoe UI", system-ui, sans-serif;

    --t-micro: 0.75rem;    /* 12 */
    --t-meta:  0.8125rem;  /* 13 */
    --t-body:  0.9375rem;  /* 15 */
    --t-sub:   1.125rem;   /* 18 */
    --t-title: 1.375rem;   /* 22 */
    --t-page:  1.75rem;    /* 28 */
    --t-hero:  2.5rem;     /* 40 */

    /* space */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;

    /* geometry */
    --r-sm:   6px;
    --r:     10px;
    --r-lg:  14px;
    --r-full: 999px;

    --shadow-sm: 0 1px 2px rgba(18, 22, 42, .05);
    --shadow-md: 0 4px 14px -3px rgba(18, 22, 42, .10), 0 2px 4px -2px rgba(18, 22, 42, .04);
    --shadow-lg: 0 16px 36px -10px rgba(18, 22, 42, .18);

    --shell: 1200px;
}

/* ---------- 2. base ---------- */
/* A small reset of its own, so the stale compiled Tailwind build (and its
   preflight) is no longer needed on the page. */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

img, svg, video { max-inline-size: 100%; }
img, svg { vertical-align: middle; }

button, input, select, textarea { font-family: inherit; font-size: 100%; color: inherit; }
button { background: none; border: 0; }

h1, h2, h3, h4 { font-weight: 600; line-height: 1.3; }
p { margin-block: 0 1em; }
ul, ol { margin-block: 0 1em; }

table { border-collapse: collapse; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--ui);
    font-size: var(--t-body);
    line-height: 1.7;
    font-weight: 400;
    letter-spacing: -0.003em;
    -webkit-font-smoothing: antialiased;
}

/* Tabular figures everywhere numbers are compared down a column. */
table, .tabular, .counter__n, .row__id, .stat__n, time { font-variant-numeric: tabular-nums; }

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

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

hr { border: 0; border-top: 1px solid var(--line); margin: var(--s5) 0; }

::placeholder { color: var(--text-3); opacity: 1; }

/* ---------- 3. type ---------- */

.display { font-family: var(--display); font-weight: 600; line-height: 1.3; letter-spacing: -0.015em; }

.t-hero  { font-size: var(--t-hero);  }
.t-page  { font-size: var(--t-page);  }
.t-title { font-size: var(--t-title); }
.t-sub   { font-size: var(--t-sub);   }
.t-meta  { font-size: var(--t-meta);  }
.t-micro { font-size: var(--t-micro); }

.muted  { color: var(--text-2); }
.faint  { color: var(--text-3); }
.prose  { max-width: 72ch; }
.nowrap { white-space: nowrap; }

/* ---------- 4. brand mark ---------- */

/* The university seal. It is a round mark carrying its own colours, so it sits
   on the page directly rather than inside the tinted tile the old letter mark
   needed to read as a logo. */
.brandmark {
    display: block;
    /* A little larger than the letter tile it replaced: the seal carries fine
       detail, so it needs the extra pixels to stay recognisable in the bar. */
    inline-size: 2.5rem;
    block-size: 2.5rem;
    object-fit: contain;
    flex: none;
    user-select: none;
}
/* `margin-inline: auto`, because the mark is a block box: the centred text in
   the blocks that carry the large mark aligns text, not blocks, so without this
   the seal sat against the start edge instead of over the heading. The base
   mark must not take it — there it is a flex item beside the wordmark, and an
   auto margin would shove the two apart. */
.brandmark--lg { inline-size: 6rem; block-size: 6rem; margin-inline: auto; }

/* ---------- 5. shell ---------- */

.shell { max-inline-size: var(--shell); margin-inline: auto; padding-inline: var(--s4); }
@media (min-width: 640px) { .shell { padding-inline: var(--s5); } }

.app { min-block-size: 100dvh; display: flex; flex-direction: column; }
/* Basis `auto`, not 0: with a zero basis the main column is sized from the
   viewport and taller pages push the footer into the middle of the page. */
.app__main { flex: 1 0 auto; padding-block: var(--s6) var(--s8); }

/* ---------- 6. masthead ---------- */

.masthead {
    background: rgba(255, 255, 255, .86);
    backdrop-filter: saturate(180%) blur(12px);
    border-block-end: 1px solid var(--line);
    position: sticky;
    inset-block-start: 0;
    z-index: 50;
}
.masthead__bar { display: flex; align-items: center; gap: var(--s4); block-size: 64px; }
.masthead__mark {
    display: flex;
    align-items: center;
    gap: var(--s3);
    color: inherit;
    /* Shrinkable, not `flex: none`: at phone widths the two-line brand held its
       full width and pushed the whole bar past the viewport, which made every
       page scroll sideways. It now gives way to the tools and ellipsises. */
    min-inline-size: 0;
}
.masthead__text {
    /* Block, not the default inline: `overflow`/`text-overflow` have no effect
       on a non-replaced inline box, so the name overlapped the tools instead
       of ellipsising. `min-inline-size: 0` lets it shrink below its content. */
    display: block;
    min-inline-size: 0;
    overflow: hidden;
}
.masthead__mark:hover { color: inherit; }
.masthead__name {
    display: block;
    font-family: var(--display);
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text);
}
.masthead__org {
    display: block;
    font-size: 0.6875rem;
    font-weight: 300;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* The org line is the first thing to go when the bar runs out of room. */
@media (max-width: 640px) { .masthead__org { display: none; } }

.nav { display: none; align-items: center; gap: var(--s1); margin-inline-start: auto; }
@media (min-width: 1024px) { .nav { display: flex; } }

.nav__link {
    display: block;
    padding: var(--s2) var(--s3);
    color: var(--text-2);
    font-size: var(--t-meta);
    font-weight: 500;
    border-radius: var(--r-sm);
    white-space: nowrap;
    transition: background-color .14s ease, color .14s ease;
}
.nav__link:hover { color: var(--text); background: var(--surface-2); }
.nav__link[aria-current="page"] { color: var(--brand); background: var(--brand-soft); }

.masthead__tools { display: flex; align-items: center; gap: var(--s2); margin-inline-start: auto; }
@media (min-width: 1024px) { .masthead__tools { margin-inline-start: var(--s4); } }

.iconbtn {
    position: relative;
    display: grid;
    place-items: center;
    inline-size: 2.25rem;
    block-size: 2.25rem;
    flex: none;
    border: 0;
    background: transparent;
    color: var(--text-2);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background-color .14s ease, color .14s ease;
}
.iconbtn:hover { color: var(--text); background: var(--surface-2); }
.iconbtn__count {
    position: absolute;
    /* Sat on the button's corner rather than over the bell, so a two-digit
       count never hides the icon it belongs to. */
    inset-block-start: -1px;
    inset-inline-end: -3px;
    min-inline-size: 16px;
    padding-inline: 4px;
    background: var(--bad);
    color: #FFF;
    font-size: 10px;
    font-weight: 500;
    line-height: 16px;
    border-radius: var(--r-full);
    text-align: center;
    box-shadow: 0 0 0 2px var(--surface);
}

/* user menu */
.usermenu { position: relative; }
.usermenu__trigger {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s1) var(--s2) var(--s1) var(--s3);
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--r-full);
    font: inherit;
    font-size: var(--t-meta);
    cursor: pointer;
    transition: border-color .14s ease, background-color .14s ease;
}
.usermenu__trigger:hover { background: var(--surface-2); border-color: var(--line-2); }
.usermenu__initial {
    display: grid;
    place-items: center;
    inline-size: 1.75rem;
    block-size: 1.75rem;
    border-radius: var(--r-full);
    background: var(--brand-soft);
    color: var(--brand-deep);
    font-size: var(--t-meta);
    font-weight: 600;
    flex: none;
}
.usermenu__label { display: none; max-inline-size: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 640px) { .usermenu__label { display: block; } }

.menu {
    position: absolute;
    inset-block-start: calc(100% + 8px);
    inset-inline-end: 0;
    min-inline-size: 15rem;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-lg);
    padding-block: var(--s1);
    z-index: 60;
}
.menu[hidden] { display: none; }
.menu__head { padding: var(--s2) var(--s4) var(--s3); border-block-end: 1px solid var(--line); }
.menu__item {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) var(--s4);
    color: var(--text);
    font-size: var(--t-meta);
    background: none;
    border: 0;
    inline-size: 100%;
    text-align: start;
    font-family: inherit;
    cursor: pointer;
}
.menu__item:hover { background: var(--surface-2); color: var(--text); }
.menu__item--danger { color: var(--bad); }
.menu__item--danger:hover { color: var(--bad); background: var(--bad-soft); }
.menu__sep { block-size: 1px; background: var(--line); margin-block: var(--s1); }

/* mobile drawer */
.drawer { display: block; background: var(--surface); border-block-start: 1px solid var(--line); }
.drawer[hidden] { display: none; }
@media (min-width: 1024px) { .drawer { display: none !important; } }
.drawer__link {
    display: block;
    padding: var(--s3) var(--s4);
    color: var(--text-2);
    font-size: var(--t-meta);
    border-block-end: 1px solid var(--line);
}
.drawer__link[aria-current="page"] { color: var(--brand); background: var(--brand-soft); font-weight: 500; }

/* ---------- 7. page head ---------- */

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--s4);
    flex-wrap: wrap;
    margin-block-end: var(--s5);
}
.page-head__title {
    margin: 0;
    font-family: var(--display);
    font-size: var(--t-page);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.02em;
}
.page-head__note { margin: var(--s1) 0 0; color: var(--text-2); font-size: var(--t-meta); }
.page-head__actions { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }

.backlink {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);
    color: var(--text-2);
    font-size: var(--t-meta);
    margin-block-end: var(--s4);
}
.backlink:hover { color: var(--brand); }

/* ---------- 8. panel ---------- */

.panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
}
.panel + .panel { margin-block-start: var(--s5); }
.panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    flex-wrap: wrap;
    padding: var(--s4) var(--s5);
    border-block-end: 1px solid var(--line);
}
.panel__title { margin: 0; font-size: var(--t-body); font-weight: 600; letter-spacing: -0.01em; }
.panel__body { padding: var(--s5); }
.panel__body--flush { padding: 0; }
.panel__foot { padding: var(--s4) var(--s5); border-block-start: 1px solid var(--line); background: var(--surface-2); border-end-start-radius: var(--r-lg); border-end-end-radius: var(--r-lg); }

/* Tabs in a panel head. The head keeps its horizontal padding but gives up its
   vertical padding to the tabs, so each tab's underline can sit on the head's
   own rule rather than floating above it. */
.panel__head--tabs { padding-block: 0; flex-wrap: nowrap; }
.tabs {
    display: flex;
    gap: var(--s4);
    /* These titles are short Arabic sentences, not one-word labels. The strip
       shrinks and scrolls rather than wrapping, which would leave the trailing
       link with no room, or widening the panel past a phone. */
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow-x: auto;
    scrollbar-width: none;
    margin-block-end: -1px;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
    flex: none;
    padding-block: var(--s4);
    border: 0;
    border-block-end: 2px solid transparent;
    background: none;
    color: var(--text-2);
    font-family: var(--ui);
    font-size: var(--t-meta);
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
    transition: color .14s ease, border-color .14s ease;
}
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--brand); border-block-end-color: var(--brand); }
.panel__head--tabs .desk-link { flex: none; }

/* ---------- 9. counters as filters ---------- */

.counters {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--s3);
    margin-block-end: var(--s5);
}
.counter {
    padding: var(--s4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
    color: var(--text);
    text-align: start;
    transition: border-color .14s ease, box-shadow .14s ease, transform .14s ease;
}
.counter:hover { border-color: var(--line-2); box-shadow: var(--shadow-md); color: var(--text); }
.counter[aria-current="true"] { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); }
.counter__n { display: block; font-size: var(--t-title); font-weight: 600; line-height: 1.2; letter-spacing: -0.02em; }
.counter__l { display: block; font-size: var(--t-micro); color: var(--text-2); font-weight: 300; }
.counter--late .counter__n { color: var(--bad); }
.counter--wait .counter__n { color: var(--warn); }
.counter--done .counter__n { color: var(--ok); }

/* ---------- 10. rows ---------- */

.register { display: block; }
.row {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--s2) var(--s4);
    padding: var(--s4) var(--s5);
    border-block-end: 1px solid var(--line);
    color: var(--text);
    transition: background-color .14s ease;
}
.row:last-child { border-block-end: 0; }
.row:hover { background: var(--surface-2); color: var(--text); }
.row--plain { grid-template-columns: 1fr auto; }
.row__id {
    font-size: var(--t-meta);
    font-weight: 500;
    color: var(--text-3);
    min-inline-size: 3ch;
}
.row__main { min-inline-size: 0; }
.row__title { font-weight: 500; line-height: 1.5; }
.row__sub { margin-block-start: 2px; color: var(--text-2); font-size: var(--t-meta); }
.row__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s1) var(--s3);
    margin-block-start: 2px;
    color: var(--text-3);
    font-size: var(--t-meta);
    font-weight: 300;
}
.row__meta > * { display: inline-flex; align-items: center; gap: var(--s1); }
/* A hairline between facts, so a location, a division and a date do not read
   as one run-on phrase. */
.row__meta > * + * { border-inline-start: 1px solid var(--line-2); padding-inline-start: var(--s3); }
.row__end { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 640px) {
    .row { grid-template-columns: auto 1fr; padding-inline: var(--s4); }
    .row__end { grid-column: 1 / -1; justify-content: flex-start; }
}

/* ---------- 11. status ---------- */

.state {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    padding: 3px var(--s3) 3px var(--s3);
    border-radius: var(--r-full);
    background: var(--surface-2);
    color: var(--text-2);
    font-size: var(--t-micro);
    font-weight: 500;
    white-space: nowrap;
    line-height: 1.5;
}
.state::before {
    content: "";
    inline-size: 6px;
    block-size: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}
.state--new  { background: var(--surface-2);  color: var(--text-2); }
.state--wait { background: var(--warn-soft);  color: var(--warn); }
.state--done { background: var(--ok-soft);    color: var(--ok); }
.state--late,
.state--fail { background: var(--bad-soft);   color: var(--bad); }
.state--off  { background: var(--surface-2);  color: var(--text-3); }

.tag {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--s2);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    font-size: var(--t-micro);
    font-weight: 400;
    color: var(--text-2);
    white-space: nowrap;
}
.tag--seal  { background: var(--brand-soft); color: var(--brand-deep); }
.tag--ochre { background: var(--warn-soft);  color: var(--warn); }
.tag--blood { background: var(--bad-soft);   color: var(--bad); }

/* ---------- 12. buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);
    padding: var(--s2) var(--s4);
    min-block-size: 38px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    font-family: var(--ui);
    font-size: var(--t-meta);
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color .14s ease, border-color .14s ease, color .14s ease, box-shadow .14s ease;
}
.btn:disabled, .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

.btn--primary { background: var(--brand); border-color: var(--brand); color: #FFF; box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--brand-deep); border-color: var(--brand-deep); color: #FFF; }

.btn--quiet { border-color: var(--line-2); color: var(--text); background: var(--surface); box-shadow: var(--shadow-sm); }
.btn--quiet:hover { background: var(--surface-2); color: var(--text); }

.btn--bare { color: var(--text-2); padding-inline: var(--s2); }
.btn--bare:hover { color: var(--brand); background: var(--brand-soft); }

.btn--danger { background: var(--bad); border-color: var(--bad); color: #FFF; box-shadow: var(--shadow-sm); }
.btn--danger:hover { background: #C22B37; border-color: #C22B37; color: #FFF; }

.btn--sm { min-block-size: 30px; padding: var(--s1) var(--s3); font-size: var(--t-micro); }
.btn--lg { min-block-size: 46px; padding: var(--s3) var(--s5); font-size: var(--t-body); border-radius: var(--r); }
.btn--block { inline-size: 100%; }

.btn svg { inline-size: 1rem; block-size: 1rem; flex: none; }
.btn--lg svg { inline-size: 1.15rem; block-size: 1.15rem; }

/* ---------- 13. forms ---------- */

.field { margin-block-end: var(--s5); }
.field:last-child { margin-block-end: 0; }

.label { display: block; margin-block-end: var(--s2); font-size: var(--t-meta); font-weight: 500; }
.label__opt { font-weight: 300; color: var(--text-3); }

.input, .select, .textarea {
    inline-size: 100%;
    padding: var(--s2) var(--s3);
    min-block-size: 40px;
    border: 1px solid var(--line-2);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--text);
    font-family: var(--ui);
    font-size: var(--t-body);
    line-height: 1.5;
    box-sizing: border-box;
    transition: border-color .14s ease, box-shadow .14s ease;
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--text-3); }
.input:focus, .select:focus, .textarea:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-ring);
    outline: none;
}
.textarea { min-block-size: 96px; resize: vertical; line-height: 1.7; }
.select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23808AA3' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: left var(--s3) center;
    background-size: 12px;
    /* The arrow is drawn on the physical left, which under this RTL interface is
       the inline END. So the clearance belongs on the end side — with it on the
       start side instead, the arrow had only its own 12px offset to sit in and a
       long option ran underneath it, while every select's text sat 32px from the
       edge where the inputs beside it use 12px. */
    padding-inline-end: var(--s6);
    padding-inline-start: var(--s3);
}
/* File picker: the browser's own control renders English text that cannot be
   translated, so the real input is hidden behind a labelled button. */
.filefield { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.filefield input[type="file"] { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; }
.filefield__btn {
    display: inline-flex;
    align-items: center;
    padding: var(--s2) var(--s4);
    min-block-size: 38px;
    border: 1px solid var(--line-2);
    border-radius: var(--r-sm);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    font-size: var(--t-meta);
    font-weight: 500;
    cursor: pointer;
}
.filefield__btn:hover { background: var(--surface-2); }
.filefield input[type="file"]:focus-visible + .filefield__btn { outline: 2px solid var(--brand); outline-offset: 2px; }
.filefield__name { font-size: var(--t-meta); color: var(--text-3); }

.hint { display: block; margin-block-start: var(--s1); font-size: var(--t-micro); color: var(--text-3); }
.error, .field-validation-error { display: block; margin-block-start: var(--s1); font-size: var(--t-micro); color: var(--bad); }
.input-validation-error { border-color: var(--bad) !important; }

.grid2 { display: grid; gap: var(--s5); }
@media (min-width: 700px) { .grid2 { grid-template-columns: 1fr 1fr; } }
.grid3 { display: grid; gap: var(--s5); }
@media (min-width: 700px)  { .grid3 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .grid3 { grid-template-columns: repeat(3, 1fr); } }
.span2 { grid-column: 1 / -1; }

/* choice cards */
.choices { display: grid; gap: var(--s3); }
@media (min-width: 700px) { .choices--2 { grid-template-columns: 1fr 1fr; } }
.choice { position: relative; display: block; }
.choice input { position: absolute; inset-inline-start: var(--s3); inset-block-start: calc(var(--s3) + 5px); }
.choice__box {
    display: block;
    padding: var(--s3) var(--s4);
    padding-inline-start: var(--s6);
    border: 1px solid var(--line-2);
    border-radius: var(--r);
    background: var(--surface);
    cursor: pointer;
    block-size: 100%;
    box-sizing: border-box;
    transition: border-color .14s ease, background-color .14s ease, box-shadow .14s ease;
}
.choice__box:hover { border-color: var(--text-3); }
.choice input:checked + .choice__box { border-color: var(--brand); background: var(--brand-soft); box-shadow: 0 0 0 3px var(--brand-ring); }
.choice input:focus-visible + .choice__box { outline: 2px solid var(--brand); outline-offset: 2px; }
.choice__t { display: block; font-weight: 500; font-size: var(--t-meta); }
.choice__d { display: block; font-size: var(--t-micro); color: var(--text-2); line-height: 1.6; font-weight: 300; }

.checkline { display: flex; align-items: flex-start; gap: var(--s2); font-size: var(--t-meta); }
.checkline input { margin-block-start: 6px; flex: none; }

/* filter bar */
.filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--s3);
    padding: var(--s4) var(--s5);
    border-block-end: 1px solid var(--line);
}
.filters .field { margin: 0; flex: 1 1 11rem; }
.filters .label { font-size: var(--t-micro); color: var(--text-2); font-weight: 400; }

/* ---------- 14. tables ---------- */

.table { inline-size: 100%; border-collapse: collapse; font-size: var(--t-meta); }
.table th, .table td { padding: var(--s3) var(--s4); text-align: start; vertical-align: middle; }
.table thead th {
    font-weight: 500;
    font-size: var(--t-micro);
    color: var(--text-2);
    background: var(--surface-2);
    white-space: nowrap;
}
.table tbody tr { border-block-start: 1px solid var(--line); }
.table tbody tr:hover { background: var(--surface-2); }
.table--ruled th, .table--ruled td { border: 1px solid var(--line-2); }
.table--ruled thead th { background: var(--surface-2); }
.tablewrap { overflow-x: auto; }

/* ---------- 15. notes & empty states ---------- */

.note {
    padding: var(--s3) var(--s4);
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
    font-size: var(--t-meta);
    margin-block-end: var(--s5);
}
.note__t { font-weight: 600; margin-block-end: 2px; }
.note--ok   { border-color: #B9E7DE; background: var(--ok-soft);   color: #0A6E60; }
.note--wait { border-color: #F2DCB4; background: var(--warn-soft); color: #8F560A; }
.note--bad  { border-color: #F6C4C9; background: var(--bad-soft);  color: #A82831; }
.note ul { margin: var(--s1) 0 0; padding-inline-start: var(--s4); }
.note p:last-child { margin-block-end: 0; }

.empty { padding: var(--s6) var(--s5); text-align: center; }
.empty__t { font-family: var(--display); font-size: var(--t-sub); font-weight: 600; margin: 0 0 var(--s2); letter-spacing: -0.01em; }
.empty__d { margin: 0 auto var(--s4); max-inline-size: 46ch; color: var(--text-2); font-size: var(--t-meta); font-weight: 300; }

/* ---------- 16. definition rows ---------- */

.facts { display: grid; gap: 0; }
.fact {
    display: grid;
    grid-template-columns: minmax(8rem, 12rem) 1fr;
    gap: var(--s4);
    padding: var(--s3) 0;
    border-block-end: 1px solid var(--line);
    font-size: var(--t-meta);
}
.fact:last-child { border-block-end: 0; }
.fact__k { color: var(--text-2); font-weight: 300; }
.fact__v { font-weight: 500; }
@media (max-width: 560px) { .fact { grid-template-columns: 1fr; gap: 0; } }

/* ---------- 17. thread / comments ---------- */

.thread { display: grid; gap: var(--s4); }
/* Replies indent one step per level. Three levels deep at phone width, the
   full indent no longer leaves the innermost reply room, so it tightens. */
.thread--replies {
    margin-block-start: var(--s4);
    padding-inline-start: var(--s4);
    border-inline-start: 2px solid var(--line);
}
@media (max-width: 640px) { .thread--replies { padding-inline-start: var(--s2); } }
/* Under ~400px the rule itself is the whole indent, so a three-deep thread
   still fits the narrowest phones in use. The avatars step down too, further
   down this section — after .post__who, or the base size would win. */
@media (max-width: 400px) { .thread--replies { padding-inline-start: 0; } }
/* `minmax(0, 1fr)`, not `1fr`: a grid track's automatic minimum is its content,
   so a long unbroken word in a comment widened the column past its share and
   pushed the page sideways. */
.post { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s3); }
.post__who {
    display: grid;
    place-items: center;
    inline-size: 2.25rem;
    block-size: 2.25rem;
    border-radius: var(--r-full);
    background: var(--surface-2);
    color: var(--text-2);
    font-weight: 600;
    font-size: var(--t-meta);
    flex: none;
}
.post__body { border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s4); background: var(--surface); }
.post--mine .post__who { background: var(--brand-soft); color: var(--brand-deep); }
.post--mine .post__body { background: var(--brand-soft); border-color: #DDDAFB; }
.post__head { display: flex; gap: var(--s3); align-items: baseline; flex-wrap: wrap; margin-block-end: var(--s1); }
.post__name { font-weight: 500; font-size: var(--t-meta); }
.post__time { font-size: var(--t-micro); color: var(--text-3); }
.post__text { margin: 0; white-space: pre-line; font-size: var(--t-meta); }

@media (max-width: 400px) { .post__who { inline-size: 1.75rem; block-size: 1.75rem; font-size: var(--t-micro); } }

/* ---------- 18. stat readouts ---------- */

.stats { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); }
.stat { padding: var(--s4) var(--s5); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-sm); }
.stat__n { display: block; font-size: var(--t-page); font-weight: 600; line-height: 1.15; letter-spacing: -0.02em; }
.stat__l { display: block; font-size: var(--t-meta); color: var(--text-2); font-weight: 300; }

.bar { block-size: 6px; background: var(--surface-2); border-radius: var(--r-full); overflow: hidden; }
.bar__fill { display: block; block-size: 100%; background: var(--brand); border-radius: var(--r-full); }

/* ---------- 19. footer ---------- */

.footer { border-block-start: 1px solid var(--line); background: var(--surface); color: var(--text-3); font-size: var(--t-micro); }
.footer__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3); padding-block: var(--s4); }
.footer a { color: var(--text-3); }
.footer a:hover { color: var(--brand); }

/* ---------- 20. utility ---------- */

.stack > * + * { margin-block-start: var(--s4); }
.stack-sm > * + * { margin-block-start: var(--s2); }
.stack-lg > * + * { margin-block-start: var(--s5); }
.inline { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
/* Controls carry `inline-size: 100%` so they fill a form field. In an inline row
   that reads as "claim the whole row", and the row wraps: a status picker and its
   button ended up stacked on separate lines, each stretched across the cell. Only
   selects are freed — a text input in an inline row is a composer and should still
   take the space that is left (see the discussion reply box). */
.inline > .select, .inline-end > .select { inline-size: auto; }
.inline-end { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; justify-content: flex-end; }
.between { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; }
/* Visually hidden, still announced. Pinned to the start corner on purpose:
   left unpinned it resolves to its static position, and inside a horizontally
   scrolled table that position sits past the page edge — with no positioned
   ancestor to clip it, a stray label there stretched the whole document and
   every page carrying one scrolled sideways on a phone. Reading order comes
   from the DOM, so pinning costs nothing. */
/* Hidden from sight, kept for screen readers — and left where it sits.
   No inset is given on purpose: with inset-block-start/inline-start at 0 and no
   positioned ancestor, every one of these landed in the page's top corner. That
   is invisible until one of them can take focus, and the checklist's ✓/✗ are
   exactly that — a radio hidden behind its label. Pressing a tick focused a
   control parked at the top of the document, so the browser scrolled the whole
   page up there, and the technician had to scroll back down for every row.
   Without an inset the element stays at its static position, where it belongs. */
.sr {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
.ltr { direction: ltr; }
/* Legacy scripts toggle a `hidden` class rather than the attribute; kept so
   they keep working once the Tailwind CDN is dropped. */
[hidden], .hidden { display: none !important; }
.narrow { max-inline-size: 34rem; margin-inline: auto; }
.medium { max-inline-size: 52rem; margin-inline: auto; }

/* ---------- 20b. touch ---------- */
/* Placed after the base rules on purpose: these carry no extra specificity and
   only win by order. */

@media (pointer: coarse) {
    /* iOS Safari zooms the whole page when a control it focuses sets type
       below 16px, and never zooms back out. The controls read at 15px on a
       pointer device and step up to 16px on a finger. */
    .input, .select, .textarea { font-size: 16px; }

    /* 30px is a comfortable click and an awkward tap, and the buttons wearing
       this size are real actions — delete, pause, mark as read. */
    .btn--sm { min-block-size: 40px; padding-inline: var(--s3); }

    /* The bell and the drawer button are the only way into notifications and
       navigation on a phone. */
    .iconbtn { inline-size: 2.5rem; block-size: 2.5rem; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- 21. print ---------- */

@media print {
    .masthead, .footer, .page-head__actions, .noprint { display: none !important; }
    body { background: #FFF; font-size: 12px; }
    .panel { border: 0; box-shadow: none; }
    .app__main { padding: 0; }
}
