/* Ijtema Championship — Local Ijtema league tables
   Dark scheme, palette from `National-Ijtema2026 Design Scheme.md` (main
   Khuddam scheme). STOP carries the championship title, Poppins carries
   everything else; both are served from Fonts/ rather than a CDN, so the
   page renders identically on a terminal with no network. */

@font-face {
    font-family: "STOP";
    src: url("Fonts/STOP.ttf") format("truetype");
    font-display: block;
}

@font-face { font-family: "Poppins"; font-weight: 300; font-style: normal;
    src: url("Fonts/Poppins-Light.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Poppins"; font-weight: 400; font-style: normal;
    src: url("Fonts/Poppins-Regular.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Poppins"; font-weight: 500; font-style: normal;
    src: url("Fonts/Poppins-Medium.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Poppins"; font-weight: 600; font-style: normal;
    src: url("Fonts/Poppins-SemiBold.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Poppins"; font-weight: 700; font-style: normal;
    src: url("Fonts/Poppins-Bold.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Poppins"; font-weight: 800; font-style: normal;
    src: url("Fonts/Poppins-ExtraBold.ttf") format("truetype"); font-display: swap; }

:root {
    /* Design scheme */
    --fresh-green:  #9EC65A;
    --oceanic-teal: #4AA49A;
    --charcoal:     #2F3433;
    --cloud-white:  #F1EFEC;
    --ocean-blue:   #1E3F59;

    /* Dark surfaces derived from Charcoal */
    --ground:       #202020;
    --raised:       #333938;
    --stripe:       #383E3D;
    --line:         rgba(241, 239, 236, .08);
    --line-strong:  rgba(241, 239, 236, .16);

    --text:         #F1EFEC;
    --muted:        #9BA19F;
    --dim:          #676D6B;

    --radius:    12px;
    --radius-sm: 8px;
    --ease: cubic-bezier(.33, 1, .68, 1);

    --font: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --font-display: "STOP", "Poppins", sans-serif;
}

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

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

body {
    margin: 0;
    font-family: var(--font);
    font-size: 15px;
    font-weight: 400;
    line-height: 1.5;
    color: var(--text);
    /* The mark, scaled to fill and centred: `cover` keeps its aspect ratio
       and crops the overflow rather than stretching it. The ground colour
       stays behind it, so the page is still right if the file is missing. */
    background-color: var(--ground);
    background-image: url("images/Ijtema Logo Background.svg");
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    /* `cover` is measured against the body box, so on a page whose content is
       shorter than the window the mark stops partway down and the ground shows
       below it. Holding the body to a full viewport gives the image the whole
       height to fill. dvh first, so a phone's collapsing toolbar cannot leave
       a strip uncovered; vh for anything that does not know dvh. */
    min-height: 100vh;
    min-height: 100dvh;
    -webkit-font-smoothing: antialiased;
}

.shell {
    max-width: 1280px;
    margin: 0 auto;
    padding: 44px 34px 64px;
}

/* ---------- Masthead ---------- */

/* The title is the way back to the summary board. It looks exactly like the
   h1 it sits in — the pointer is the only thing that says it is a link. */
.homeLink {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}


.masthead {
    display: flex;
    align-items: center;
    gap: 26px;
}

.mark {
    flex: 0 0 auto;
    /* As tall as the type beside it: the eyebrow and subtitle contribute a
       fixed 71px of leading, the wordmark its own clamped size. Tracking
       the h1's clamp keeps the two in step as the masthead scales. Width
       follows from the SVG's own 616:647 viewBox. */
    height: calc(63px + clamp(2.2rem, 5.2vw, 3.55rem));
    width: auto;
    aspect-ratio: 616 / 647;
    object-fit: contain;
}

.eyebrow {
    margin: 0 0 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--oceanic-teal);
}

h1 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(2.2rem, 5.2vw, 3.55rem);
    line-height: 1;
    letter-spacing: .015em;
    text-transform: uppercase;
    color: var(--fresh-green);
}

.subtitle {
    margin: 4px 0 0;
    font-size: clamp(1.15rem, 2.4vw, 1.6rem);
    font-weight: 500;
    letter-spacing: -.01em;
    color: var(--text);
}

.subtitle b {
    font-weight: 500;
    color: var(--oceanic-teal);
}

.rule {
    height: 2px;
    margin: 26px 0 0;
    background: var(--fresh-green);
    border: 0;
}

/* ---------- Stat strip ---------- */

.stats {
    display: flex;
    flex-wrap: wrap;
    gap: 46px;
    margin: 26px 0 30px;
    padding: 0;
    list-style: none;
}

.stats b {
    display: block;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.stats b i {
    font-style: normal;
    font-weight: 300;
    font-size: 20px;
    color: var(--dim);
}

.stats li > span {
    display: block;
    margin-top: 2px;
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--muted);
}

/* ---------- Toolbar ---------- */

.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: 22px;
}

.segmented {
    display: inline-flex;
    padding: 4px;
    gap: 4px;
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: 999px;
}

.segmented button {
    appearance: none;
    border: 0;
    cursor: pointer;
    padding: 8px 22px;
    font: inherit;
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--muted);
    background: transparent;
    border-radius: 999px;
    transition: color .18s var(--ease), background .18s var(--ease);
}

.segmented button:hover { color: var(--text); }

.segmented button[aria-selected="true"] {
    color: #222726;
    background: var(--fresh-green);
}

.field {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 42px;
    padding: 0 16px;
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: 999px;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}

.field:focus-within {
    border-color: var(--oceanic-teal);
    box-shadow: 0 0 0 3px rgba(74, 164, 154, .2);
}

.field label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--oceanic-teal);
    white-space: nowrap;
}

.field select,
.field input {
    appearance: none;
    border: 0;
    outline: 0;
    background: transparent;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
    max-width: 220px;
}

.field select {
    padding-right: 20px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239BA19F' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right center;
}

.field select option { background: var(--raised); color: var(--text); }

.field input::placeholder { color: var(--dim); font-weight: 400; }

.field.hidden { display: none; }

/* Tier switches — the box fills with colour rather than carrying a tick */

.tiers {
    display: inline-flex;
    align-items: center;
    gap: 16px;
    height: 42px;
    padding: 0 18px;
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: 999px;
}

.tiers-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--oceanic-teal);
    white-space: nowrap;
}

.tiers.hidden { display: none; }

.check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--muted);
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: color .18s var(--ease);
}

.check:hover { color: var(--text); }

.check input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.check .box {
    width: 17px;
    height: 17px;
    border: 1.5px solid var(--line-strong);
    border-radius: 6px;
    background: transparent;
    transition: background .18s var(--ease), border-color .18s var(--ease),
                box-shadow .18s var(--ease);
}

.check input:checked + .box {
    background: var(--fresh-green);
    border-color: var(--fresh-green);
}

.check input:focus-visible + .box {
    box-shadow: 0 0 0 3px rgba(74, 164, 154, .35);
}

.check input:checked ~ * { color: var(--text); }

.check:has(input:checked) { color: var(--text); font-weight: 600; }

.check:has(input:disabled) { cursor: not-allowed; color: var(--dim); }
.check:has(input:disabled):hover { color: var(--dim); }
.check input:disabled + .box { border-color: rgba(241, 239, 236, .09); }

.spacer { flex: 1 1 auto; }

.switch {
    padding: 9px 16px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    transition: color .18s var(--ease), border-color .18s var(--ease);
}

.switch:hover { color: var(--fresh-green); border-color: var(--fresh-green); }

.meta {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--dim);
    white-space: nowrap;
}

/* ---------- Table ---------- */

.scroller { overflow-x: auto; overscroll-behavior-x: contain; }

table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    padding: 14px 16px;
    background: var(--ocean-blue);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--cloud-white);
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
}

thead th:first-child { padding-left: 26px; border-radius: var(--radius-sm) 0 0 0; }
thead th:last-child  { padding-right: 26px; border-radius: 0 var(--radius-sm) 0 0; }

/* Figure columns in teal, the Points column in Cloud White */
thead th:not(.left)  { color: var(--oceanic-teal); }
thead tr:first-child th:last-child { color: var(--cloud-white); }

/* ---------- Grouped headings ----------
   With more than one tier on, a category carries a column per tier: the
   category name spans them, each tier names its own column underneath.
   The spanning cell sorts nothing, so it does not behave like a button. */

thead tr.groupRow th.group {
    text-align: center;
    color: var(--cloud-white);
    cursor: default;
}

thead tr.groupRow th.group:hover { background: var(--ocean-blue); }

/* A hairline between the groups, so a pair reads as one heading rather
   than two columns that happen to sit together. */
thead tr.groupRow th + th { border-left: 1px solid rgba(241, 239, 236, .14); }

/* A band of its own, a shade darker than the heading above it. */
thead tr.tierRow th {
    padding-top: 7px;
    padding-bottom: 10px;
    background: #18344A;
    font-size: 9.5px;
    letter-spacing: .1em;
    color: var(--cloud-white);
}

thead tr.tierRow th:hover { background: #1C3D56; }

/* Rank, Region and Points hold their place in the tier row without
   naming a tier, so the band runs the width of the table. */
/* The sort arrow takes no width in this row: an invisible arrow inside
   the cell would centre the label on "LOCAL plus an arrow" rather than on
   the column. It overflows to the right of the label instead, and the
   offset is positional so it still costs nothing. */
thead tr.tierRow th .arrow {
    display: inline-block;
    width: 0;
    margin-left: 0;
    position: relative;
    left: 4px;
    overflow: visible;
}

thead tr.tierRow th.spacer { cursor: default; }
thead tr.tierRow th.spacer:hover { background: #18344A; }

/* The quieter half of each pair (see categoryColumns in app.js). */
td.quiet { color: #8D9391; }

/* The corner radii and the wide outer padding belong to the first row. */
thead tr.tierRow th:first-child,
thead tr.tierRow th:last-child {
    padding-left: 16px;
    padding-right: 16px;
    border-radius: 0;
}

/* A category the tier does not score. Distinct from a zero, which is a
   figure the Region earned. */
td .dash { color: var(--line-strong); }

thead th.left { text-align: left; }

thead th:hover { background: #25496510; background-color: #26506F; }

thead th .arrow { opacity: 0; margin-left: 6px; font-size: 9px; }
thead th[aria-sort] .arrow { opacity: 1; }

tbody tr { border-bottom: 1px solid var(--line); }
tbody tr:nth-child(even) { background: rgba(241, 239, 236, .035); }
tbody tr:hover { background: rgba(241, 239, 236, .06); }

tbody td {
    padding: 15px 16px;
    text-align: center;
    white-space: nowrap;
    font-size: 15px;
    font-weight: 500;
}

td.left { text-align: left; }

/* Rank, with the leader bar the printed tables use */

td.rank {
    position: relative;
    width: 84px;
    padding-left: 26px;
    text-align: left;
    font-size: 14px;
    font-weight: 500;
    color: var(--muted);
}

tr.top3 td.rank::before {
    content: "";
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 26px;
    border-radius: 2px;
    background: var(--fresh-green);
}

/* Name */

td.name {
    min-width: 220px;
    text-align: left;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -.01em;
}

td.name .sub {
    display: block;
    margin-top: 2px;
    font-size: 11.5px;
    font-weight: 400;
    letter-spacing: .01em;
    color: var(--dim);
}

.tag {
    display: inline-block;
    margin-left: 10px;
    padding: 2px 9px 3px;
    border: 1px solid rgba(241, 239, 236, .18);
    border-radius: 999px;
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--muted);
    vertical-align: 2px;
}

/* Numbers */

td .sub {
    display: block;
    margin-top: 1px;
    font-size: 11.5px;
    font-weight: 400;
    letter-spacing: .01em;
    color: var(--dim);
}

td.num.zero { color: var(--dim); font-weight: 400; }

td.pts {
    padding-right: 26px;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--fresh-green);
}

td.pts.zero { color: var(--dim); }

/* The decimal, quieter than the whole number — as the /144 is in the
   stat strip. */
.dec {
    /* Proportional rather than fixed, so it sits the same distance below
       the figure in the table (19px) and in the rollup strip (22px). */
    font-size: .88em;
    font-weight: 300;
    color: var(--dim);
}

td.idx { color: var(--muted); font-size: 14px; }

/* A Qiadat that filed no report reads greyed, as in the printed tables */
tr.silent td,
tr.silent td.name { color: var(--dim); }
tr.silent td.pts { color: var(--dim); }

/* ---------- Region summary strip ---------- */

.rollup {
    display: flex;
    flex-wrap: wrap;
    gap: 38px;
    margin: 0;
    padding: 22px 26px 24px;
    border-top: 2px solid var(--fresh-green);
    list-style: none;
}

.rollup b {
    display: block;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.rollup b i {
    font-style: normal;
    font-weight: 400;
    font-size: 14px;
    color: var(--muted);
}

.rollup li > span {
    display: block;
    margin-top: 1px;
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--muted);
}

.rollup li.accent b { color: var(--fresh-green); }
/* Direct child only: the caption is teal, but the quiet decimal nested
   inside the figure keeps the grey it has everywhere else. */
.rollup li.accent > span { color: var(--oceanic-teal); }

/* ---------- Footer ---------- */

.legend {
    margin-top: 34px;
    padding-top: 26px;
    border-top: 2px solid var(--fresh-green);
}

.legend h3 {
    margin: 0 0 12px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--oceanic-teal);
}

.keys {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 32px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 13px;
    color: var(--muted);
}

.keys li { display: flex; justify-content: space-between; gap: 14px; }
.keys b { color: var(--text); font-weight: 600; margin-right: 6px; }
.keys i { font-style: normal; color: var(--dim); font-variant-numeric: tabular-nums; }
.keys span { flex: 1 1 auto; }

.legend p {
    margin: 0;
    font-size: 13px;
    line-height: 1.65;
    color: var(--muted);
}

.empty {
    padding: 60px 26px;
    text-align: center;
    color: var(--muted);
}

.empty b { display: block; color: var(--text); font-weight: 600; margin-bottom: 4px; }

.error {
    margin-top: 30px;
    padding: 22px 24px;
    background: rgba(217, 87, 70, .12);
    border: 1px solid rgba(217, 87, 70, .35);
    border-radius: var(--radius);
    color: #E6A79C;
}

.error b { display: block; color: var(--text); margin-bottom: 4px; }

@media (prefers-reduced-motion: reduce) {
    * { transition-duration: .001s !important; animation: none !important; }
}

/* ---------- Narrow screens ---------- */

@media (max-width: 900px) {
    .shell { padding: 26px 14px 48px; }
    .masthead { gap: 16px; flex-wrap: wrap; }
    .mark { height: 74px; width: auto; }
    .stats { gap: 26px; margin: 20px 0 22px; }
    .stats b { font-size: 24px; }
    .field select, .field input { max-width: 140px; }
    .meta { display: none; }
    thead th:first-child, td.rank { padding-left: 14px; }
    thead th:last-child, td.pts { padding-right: 14px; }
}

/* ---------- Capture mode ----------
   board.php?png=1. One fixed view, no controls, nothing that moves. The
   screenshot is taken at 1400px wide with deviceScaleFactor 2, so the
   shell widens to fill it and nothing may clip or scroll. */

body.capture .shell {
    max-width: 1400px;
    padding: 56px 44px 48px;
}

/* Horizontal scroll would clip the widest columns out of the capture. */
body.capture .scroller {
    overflow-x: visible;
    overflow-y: visible;
}

/* A sticky header floats to the top of the viewport, which in a full-page
   capture smears it away from the table it belongs to. */
body.capture thead th {
    position: static;
    cursor: default;
}

/* Nothing may be mid-transition when the shutter opens. */
body.capture *,
body.capture *::before,
body.capture *::after {
    transition: none !important;
    animation: none !important;
}

/* The toolbar carries the compile date on the interactive board; in
   capture mode it is not rendered, so the footer carries it instead. */
.capture-footer {
    margin: 30px 0 0;
    font-size: 13px;
    color: var(--dim);
    text-align: right;
}

/* ---------- A4 sheet ----------
   board.php?png=1&page=a4. A fixed 794x1123 CSS page captured at
   deviceScaleFactor 3, which is 2382x3369 — the geometry of the printed
   League Tables. Every sheet is the same size whether the Region has
   four Qiadats or eleven, with the legend pinned to the foot.

   The design is set at --a4-zoom of its on-screen scale, which is what
   makes the type match the printed sheets. Change that one number and
   the page reflows around it; everything else here is derived from it. */

body.capture.a4 {
    --a4-zoom: .78;
    zoom: var(--a4-zoom);
    overflow: hidden;
}

body.capture.a4 .shell {
    box-sizing: border-box;
    /* The real page divided by the zoom, so it fills 794x1123 exactly. */
    width: calc(794px / var(--a4-zoom));
    height: calc(1123px / var(--a4-zoom));
    max-width: none;
    margin: 0;
    padding: 56px 56px 40px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Pins the legend to the foot of the sheet; a short table leaves the gap
   above it rather than floating the notes up the page. */
body.capture.a4 .legend { margin-top: auto; }

body.capture.a4 .capture-footer { margin: 7px 0 0; font-size: 10px; }

/* The narrow-screen rules would otherwise fire on a 794px viewport and
   collapse the sheet to the phone layout. */
body.capture.a4 .masthead { gap: 26px; }
body.capture.a4 .mark { height: 106px; width: auto; }
body.capture.a4 .stats { gap: 46px; margin: 26px 0 30px; }
body.capture.a4 .stats b { font-size: 30px; }
body.capture.a4 thead th:first-child,
body.capture.a4 td.rank { padding-left: 26px; }
body.capture.a4 thead th:last-child,
body.capture.a4 td.pts { padding-right: 26px; }

/* clamp() on these reads from the real viewport, not the zoomed one, so
   they need pinning or the masthead shrinks to its phone size. */
body.capture.a4 h1 { font-size: 2.85rem; }
body.capture.a4 .subtitle { font-size: 1.5rem; }

/* The sheet is a fixed height, so the table has to earn its place: the
   printed League Tables carry one line per row and a tighter rhythm than
   the screen board, which is what lets twenty Regions fit above the
   legend. Sizes are in the zoomed coordinate space — divide by
   --a4-zoom to read them as page pixels. */

body.capture.a4 thead th {
    padding: 11px 12px;
    font-size: 12px;
}

body.capture.a4 thead th:first-child { padding-left: 22px; }
body.capture.a4 thead th:last-child  { padding-right: 22px; }

body.capture.a4 tbody td {
    padding: 9px 12px;
    font-size: 15.5px;
}

body.capture.a4 td.rank { width: 68px; padding-left: 22px; font-size: 14px; }
body.capture.a4 td.name { min-width: 0; font-size: 16px; }
body.capture.a4 td.pts  { padding-right: 22px; font-size: 19px; }

/* One line per row, as the printed sheets have. */
body.capture.a4 td .sub { display: none; }

body.capture.a4 tr.top3 td.rank::before { height: 20px; }

/* Legend and rollup, trimmed to leave the table its room. */
body.capture.a4 .legend {
    margin-top: auto;
    padding-top: 13px;
}

body.capture.a4 .legend h3 { margin-bottom: 6px; }
body.capture.a4 .legend p { font-size: 11px; line-height: 1.5; }
body.capture.a4 .legend p + p { margin-top: 6px; }

body.capture.a4 .rollup { padding: 16px 20px 18px; gap: 26px; }
body.capture.a4 .rollup b { font-size: 18px; }
body.capture.a4 .rollup li > span { font-size: 9px; }

body.capture.a4 .stats { gap: 34px; margin: 14px 0 16px; }
body.capture.a4 .stats b { font-size: 25px; }
body.capture.a4 .rule { margin-top: 18px; }

/* ---------- Export ----------
   Top corner of the masthead. The label is set like a table header so it
   reads as part of the furniture rather than as another control. */

.export {
    margin-left: auto;
    align-self: flex-start;
    text-align: center;
}

.export-label {
    display: block;
    margin-bottom: 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--oceanic-teal);
}

.export-actions {
    display: flex;
    justify-content: center;
    gap: 8px;
}

/* Full Set sits under the pair and spans them. */
.export-actions + .export-actions { margin-top: 8px; }
.export-actions.wide button { flex: 1 1 auto; }

.export-actions button {
    appearance: none;
    cursor: pointer;
    padding: 8px 18px;
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--muted);
    background: var(--raised);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    transition: color .18s var(--ease), border-color .18s var(--ease),
                background .18s var(--ease);
}

.export-actions button:hover:not(:disabled) {
    color: var(--fresh-green);
    border-color: var(--fresh-green);
}

.export-actions button:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 3px rgba(74, 164, 154, .35);
}

.export-actions button:disabled {
    cursor: not-allowed;
    color: var(--dim);
    border-color: rgba(241, 239, 236, .09);
    background: transparent;
}

/* Held while the server renders the sheet — a few seconds on a Pi. */
.export-actions button.busy {
    cursor: progress;
    color: var(--oceanic-teal);
    border-color: var(--oceanic-teal);
}

@media (max-width: 900px) {
    .export { margin-left: 0; width: 100%; text-align: left; }
    .export-actions { justify-content: flex-start; }
    .export-actions.wide button { flex: 0 1 auto; }
}
