@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght@0,300;0,400;0,500;0,600;1,400;1,500&family=Inter:wght@300;400;500&display=swap');

/* ===========================================================
   AFTA — Luxury / Editorial
   Standalone stylesheet. No framework, no build step.
   Elegance through restraint: nothing is rounded, nothing is loud,
   nothing moves quickly except where a person is waiting on it.
   =========================================================== */

:root {
    /* Sophisticated monochrome. Never pure black, never pure white. */
    --paper:      #F9F8F6;  /* warm alabaster */
    --ink:        #1A1A1A;  /* rich charcoal */
    --taupe:      #EBE5DE;  /* pale taupe, surface elevation */
    --warm-grey:  #6C6863;  /* secondary text */
    --gold:       #D4AF37;  /* accent only — never a large area */
    /* Gold text on alabaster is 1.98:1 and fails WCAG at any size. The system
       only ever validates gold ON charcoal (8.28:1). So: --gold for fills,
       rules, dots and text on dark; --gold-ink (5.39:1, AA) for gold text and
       focus indicators on paper. Same accent, honest contrast. */
    --gold-ink:   #7A6420;
    --on-dark:    #FFFFFF;

    /* Hairlines, by opacity of ink. */
    --rule:       rgba(26, 26, 26, 0.14);
    --rule-soft:  rgba(26, 26, 26, 0.08);

    --serif: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --sans:  'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

    /* Cinematic timing. Nothing snaps. */
    --ease:      cubic-bezier(0.25, 0.46, 0.45, 0.94);
    --dur-text:  300ms;   /* text colour — the one thing allowed to be quick */
    --dur:       500ms;   /* buttons, borders */
    --dur-slow:  700ms;   /* backgrounds, colour fields */
    --dur-image: 1500ms;  /* grayscale reveal */

    /* Space, generously. If it feels too airy, it is correct. */
    --sp-1: 0.25rem;
    --sp-2: 0.5rem;
    --sp-3: 1rem;
    --sp-4: 1.5rem;
    --sp-5: 3rem;
    --sp-6: 5rem;
    --sp-7: 8rem;

    --shell: 1600px;
}

/* ===========================
   Reset
   =========================== */

*, *::before, *::after { box-sizing: border-box; }

/* Architectural precision: nothing is rounded, anywhere. */
* { border-radius: 0 !important; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    min-height: 100vh;
    background-color: var(--paper);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.625;
    -webkit-font-smoothing: antialiased;
}

img, svg { vertical-align: middle; }
.img-fluid { max-width: 100%; height: auto; }
button { font: inherit; }

/* ===========================
   Editorial chrome
   =========================== */

/* Four hairlines at the 12-column boundaries. Architectural, not decorative. */
.gridlines {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image:
        linear-gradient(to right, var(--rule) 1px, transparent 1px),
        linear-gradient(to right, var(--rule) 1px, transparent 1px),
        linear-gradient(to right, var(--rule) 1px, transparent 1px),
        linear-gradient(to right, var(--rule) 1px, transparent 1px);
    background-size: 1px 100%;
    background-repeat: no-repeat;
    background-position: 8.333% 0, 33.333% 0, 66.666% 0, 91.666% 0;
}

/* Expensive paper. Invisible until you look for it. */
.grain {
    position: fixed;
    inset: 0;
    z-index: 50;
    pointer-events: none;
    opacity: 0.02;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Content rides above the gridlines. */
.navbar, main, .kiosk-container, .top-action-bar { position: relative; z-index: 1; }

@media (max-width: 1023.98px) {
    .gridlines { display: none; }
}

/* ===========================
   Typography
   =========================== */

h1, h2, h3, h4, h5, h6 {
    font-family: var(--serif);
    font-weight: 400;
    color: var(--ink);
    margin: 0 0 var(--sp-3);
    letter-spacing: -0.01em;
}

/* Extreme scale: massive serif against tiny tracked-out sans. */
h1, .display-4 { font-size: clamp(2.75rem, 1.2rem + 6.4vw, 8rem); line-height: 0.9; }
h2 { font-size: clamp(2rem, 1rem + 3.4vw, 4.5rem); line-height: 0.95; }
h3 { font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.25rem); line-height: 1.1; }
h4, h5, h6 { font-size: 1.25rem; line-height: 1.25; }

/* Emphasis within a headline: italic, gold. "Curated Excellence". */
h1 em, h2 em, h3 em, .headline-accent {
    font-style: italic;
    color: var(--gold-ink);
}

p { margin: 0 0 var(--sp-3); }

/* Overline. Wide tracking is where the elegance lives. */
.eyebrow {
    font-family: var(--sans);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

.micro {
    font-size: 10px;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

.lede {
    font-size: 1.125rem;
    font-weight: 300;
    line-height: 1.625;
    color: var(--warm-grey);
    max-width: 34rem;
}

/* Classic editorial opener. */
.drop-cap::first-letter {
    float: left;
    font-family: var(--serif);
    font-size: 4.5rem;
    line-height: 0.8;
    padding-right: 0.75rem;
    margin-top: 0.1em;
    color: var(--ink);
}

/* "Editorial / Vol. 01" running up the edge of an image. */
.vertical-label {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    font-size: 0.75rem;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

@media (max-width: 767.98px) {
    .vertical-label { display: none; }
}

/* Short architectural rule, used before labels. */
.rule-short {
    display: inline-block;
    width: 2rem;
    height: 1px;
    background: var(--ink);
    vertical-align: middle;
}

@media (min-width: 768px) {
    .rule-short { width: 3rem; }
}

a {
    color: var(--ink);
    text-decoration: none;
    transition: color var(--dur-text) var(--ease);
}

a:hover { color: var(--gold-ink); }

hr {
    border: 0;
    border-top: 1px solid var(--rule);
    margin: var(--sp-4) 0;
}

:focus-visible {
    outline: 1px solid var(--ink);
    outline-offset: 3px;
}

/* ===========================
   Layout
   =========================== */

.container {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: 2rem;
}

@media (min-width: 768px) {
    .container { padding-inline: 4rem; }
}

.row {
    display: flex;
    flex-wrap: wrap;
    margin-inline: calc(var(--sp-3) * -1);
}

.row > [class*="col-"] {
    padding-inline: var(--sp-3);
    width: 100%;
}

.col-12 { width: 100%; }

@media (min-width: 576px) { .col-sm-12 { width: 100%; } }

@media (min-width: 768px) {
    .col-md-4 { width: 33.3333%; }
    .col-md-6 { width: 50%; }
    .mb-md-0 { margin-bottom: 0 !important; }
}

@media (min-width: 992px) {
    .col-lg-3 { width: 25%; }
    .col-lg-4 { width: 33.3333%; }
    .col-lg-9 { width: 75%; }
    .mb-lg-0 { margin-bottom: 0 !important; }
}

/* ===========================
   Utilities (only what the views use)
   =========================== */

.d-flex   { display: flex !important; }
.d-grid   { display: grid !important; }
.d-inline { display: inline !important; }
.d-none   { display: none !important; }

.flex-column { flex-direction: column; }
.flex-wrap   { flex-wrap: wrap; }
.flex-fill   { flex: 1 1 auto; }

.justify-content-center  { justify-content: center; }
.justify-content-between { justify-content: space-between; }
.align-items-center      { align-items: center; }
.align-items-baseline    { align-items: baseline; }

.gap-2 { gap: var(--sp-2); }
.gap-3 { gap: var(--sp-3); }

.ms-auto { margin-left: auto; }
.me-auto { margin-right: auto; }

.m-0  { margin: 0 !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-1 { margin-bottom: var(--sp-1) !important; }
.mb-2 { margin-bottom: var(--sp-2) !important; }
.mb-3 { margin-bottom: var(--sp-3) !important; }
.mb-4 { margin-bottom: var(--sp-4) !important; }
.mb-5 { margin-bottom: var(--sp-5) !important; }
.mt-1 { margin-top: var(--sp-1) !important; }
.mt-2 { margin-top: var(--sp-2) !important; }
.mt-4 { margin-top: var(--sp-4) !important; }
.mt-5 { margin-top: var(--sp-5) !important; }
.my-4 { margin-block: var(--sp-4) !important; }
.me-1 { margin-right: var(--sp-1) !important; }
.ms-2 { margin-left: var(--sp-2) !important; }

.p-3  { padding: var(--sp-3) !important; }
.px-0 { padding-inline: 0 !important; }
.px-3 { padding-inline: var(--sp-3) !important; }
.py-2 { padding-block: var(--sp-2) !important; }
.pb-5 { padding-bottom: var(--sp-6) !important; }

.w-100 { width: 100% !important; }

.position-relative { position: relative; }
.position-fixed    { position: fixed; }
.bottom-0 { bottom: 0; }
.end-0    { right: 0; }

.border-bottom { border-bottom: 1px solid var(--rule); }

.text-center { text-align: center; }
.text-uppercase { text-transform: uppercase; letter-spacing: 0.25em; }
.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.text-sm { font-size: 0.875rem; }
.fs-6    { font-size: 1rem; }
.fw-bold { font-weight: 500; }

/* Semantic colour, kept within the monochrome discipline. */
.text-success { color: #4A6B4A !important; }
.text-danger  { color: #8B3A3A !important; }
.text-white   { color: var(--on-dark) !important; }
.text-dark    { color: var(--ink) !important; }
.text-muted   { color: var(--warm-grey) !important; }

/* Shadows: depth by layering, never a harsh drop. */
.shadow-sm { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02); }
.shadow    { box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12); }

/* ===========================
   Buttons
   =========================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    position: relative;
    isolation: isolate;
    /* Clips the gold slide layer, parked at translateX(-100%) just outside the
       left edge. `isolation` creates the stacking context so the layer paints
       above the button's background but below its text; only `overflow`
       confines it to the button's box. Without this the gold is always visible. */
    overflow: hidden;
    min-height: 48px;
    padding: 0 2rem;
    border: 1px solid transparent;
    background: transparent;
    color: var(--ink);
    font-family: var(--sans);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--dur) var(--ease),
                color var(--dur) var(--ease),
                border-color var(--dur) var(--ease),
                box-shadow var(--dur) var(--ease);
}

/* Gold slides in from the left.
   A ::before at z-index:-1 paints above the button's own background but below
   its text — so the spec's layered <span> markup isn't needed in any view. */
.btn-primary {
    background-color: var(--ink);
    color: var(--on-dark);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.btn-primary::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-color: var(--gold);
    transform: translateX(-100%);
    transition: transform var(--dur) var(--ease);
}

.btn-primary:hover {
    color: var(--on-dark);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.btn-primary:hover::before { transform: translateX(0); }

/* Secondary: hairline that fills with ink. */
.btn-secondary,
.btn-outline-secondary,
.btn-light,
.btn-outline-light,
.btn-info {
    border-color: var(--ink);
    color: var(--ink);
}

.btn-secondary:hover,
.btn-outline-secondary:hover,
.btn-light:hover,
.btn-outline-light:hover,
.btn-info:hover {
    background-color: var(--ink);
    color: var(--on-dark);
}

.btn-success {
    border-color: #4A6B4A;
    color: #4A6B4A;
}

.btn-success:hover { background-color: #4A6B4A; color: var(--on-dark); }

.btn-danger,
.btn-outline-danger {
    border-color: #8B3A3A;
    color: #8B3A3A;
}

.btn-danger:hover,
.btn-outline-danger:hover { background-color: #8B3A3A; color: var(--on-dark); }

.btn-warning { border-color: var(--gold); color: var(--gold-ink); }
.btn-warning:hover { background-color: var(--gold); color: var(--ink); }

.btn-outline-primary { border-color: var(--ink); color: var(--ink); }
.btn-outline-primary:hover { background-color: var(--ink); color: var(--on-dark); }

.btn:disabled,
.btn.disabled {
    opacity: 0.5;
    pointer-events: none;
    box-shadow: none;
}

.btn-sm { min-height: 40px; padding: 0 1.25rem; font-size: 0.6875rem; }
.btn-lg { min-height: 56px; padding: 0 2.5rem; }

/* The × is drawn, not iconised. */
.btn-close {
    position: relative;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--warm-grey);
    cursor: pointer;
    flex: 0 0 auto;
    transition: color var(--dur-text) var(--ease);
}

.btn-close::before,
.btn-close::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    width: 14px;
    height: 1px;
    background: currentColor;
}

.btn-close::before { transform: translate(-50%, -50%) rotate(45deg); }
.btn-close::after  { transform: translate(-50%, -50%) rotate(-45deg); }
.btn-close:hover { color: var(--gold-ink); }

/* ===========================
   Badges
   =========================== */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--rule);
    font-size: 0.625rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    line-height: 1.4;
    color: var(--warm-grey);
}

.bg-primary { border-color: var(--ink); color: var(--ink); }
.bg-success { border-color: #4A6B4A; color: #4A6B4A; }
.bg-warning { border-color: var(--gold); color: var(--gold-ink); }

.bg-info-outline      { border-color: var(--rule); color: var(--warm-grey); }
.bg-outline-success   { border-color: #4A6B4A; color: #4A6B4A; }
.bg-outline-secondary { border-color: var(--rule); color: var(--warm-grey); }
.bg-light { background: transparent; }

/* ===========================
   Cards — defined by a line, not a box
   =========================== */

.card {
    display: flex;
    flex-direction: column;
    background: transparent;
    border: 0;
    border-top: 1px solid var(--ink);
    padding: var(--sp-4) 0 0;
    color: var(--ink);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
    transition: background-color var(--dur-slow) var(--ease),
                box-shadow var(--dur-slow) var(--ease);
}

.card:hover { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06); }

.card-body { padding: var(--sp-3) 0; }

.card-header {
    padding: 0 0 var(--sp-3);
    border-bottom: 1px solid var(--rule);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

.card-title { font-family: var(--serif); font-size: 1.5rem; margin-bottom: var(--sp-2); }
.card-text  { color: var(--warm-grey); margin: 0; }

/* ===========================
   Inputs — underline only
   =========================== */

.form-label,
label {
    display: inline-block;
    margin-bottom: var(--sp-2);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

.form-control,
.form-select {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: 0.5rem 0;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--ink);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 0.875rem;
    transition: border-color var(--dur) var(--ease);
}

.form-select {
    appearance: none;
    padding-right: 1.5rem;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--ink) 50%),
        linear-gradient(135deg, var(--ink) 50%, transparent 50%);
    background-position: calc(100% - 10px) calc(50% + 1px), calc(100% - 5px) calc(50% + 1px);
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

/* Italic serif placeholder — quietly editorial. */
.form-control::placeholder {
    font-family: var(--serif);
    font-style: italic;
    color: var(--warm-grey);
    opacity: 1;
}

.form-control:focus,
.form-select:focus {
    outline: none;
    border-bottom-color: var(--gold-ink);
}

.form-control.is-invalid,
.form-select.is-invalid { border-bottom-color: #8B3A3A; }

.invalid-feedback {
    display: block;
    margin-top: var(--sp-2);
    font-size: 0.75rem;
    color: #8B3A3A;
}

.form-check {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin-bottom: var(--sp-2);
}

.form-check-input {
    width: 1rem;
    height: 1rem;
    margin: 0;
    accent-color: var(--ink);
    flex: 0 0 auto;
    cursor: pointer;
}

.form-check-label,
.form-check .form-check-label {
    margin: 0;
    letter-spacing: normal;
    text-transform: none;
    font-size: 0.875rem;
    color: var(--ink);
    cursor: pointer;
}

.white-placeholder::placeholder { color: var(--warm-grey); opacity: 1; }

/* ===========================
   Tables
   =========================== */

.table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table {
    width: 100%;
    margin-bottom: var(--sp-4);
    border-collapse: collapse;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.table th,
.table td {
    padding: 1rem 0.75rem;
    text-align: left;
    vertical-align: middle;
    border-bottom: 1px solid var(--rule-soft);
}

.table thead th {
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
    border-bottom: 1px solid var(--ink);
}

.table-bordered th,
.table-bordered td { border: 1px solid var(--rule); }

.table-striped tbody tr:nth-of-type(odd) { background-color: rgba(235, 229, 222, 0.35); }

.table-hover tbody tr { transition: background-color var(--dur) var(--ease); }
.table-hover tbody tr:hover { background-color: var(--taupe); }

.table-dark { background: transparent; }

/* ===========================
   Navbar
   =========================== */

.navbar {
    background: transparent;
    border-bottom: 1px solid var(--rule);
    padding-block: var(--sp-4);
}

.navbar > .container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
}

.navbar-brand {
    font-family: var(--serif);
    font-size: 1.5rem;
    letter-spacing: -0.01em;
    color: var(--ink);
}

.navbar-nav {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    list-style: none;
    margin: 0;
    padding: 0;
}

.nav-link {
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink);
    transition: color var(--dur) var(--ease);
}

.nav-link:hover,
.nav-link.active { color: var(--gold-ink); }

.navbar-menu { position: relative; }

.navbar-menu > summary {
    display: none;
    list-style: none;
    cursor: pointer;
    min-height: 44px;
    align-items: center;
    padding: 0 1rem;
    border: 1px solid var(--ink);
    font-size: 0.75rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
}

.navbar-menu > summary::-webkit-details-marker { display: none; }

@media (max-width: 991.98px) {
    .navbar-menu > summary { display: inline-flex; }
    .navbar-menu[open] .navbar-nav {
        position: absolute;
        right: 0;
        top: calc(100% + 0.75rem);
        flex-direction: column;
        align-items: flex-start;
        gap: var(--sp-3);
        min-width: 14rem;
        padding: var(--sp-3);
        background: var(--paper);
        border: 1px solid var(--ink);
        z-index: 30;
    }
    .navbar-menu:not([open]) .navbar-nav { display: none; }
}

/* ===========================
   List groups
   =========================== */

.list-group {
    display: flex;
    flex-direction: column;
    list-style: none;
    margin: 0;
    padding: 0;
}

.list-group-item {
    padding: var(--sp-3) 0;
    color: var(--ink);
    background: transparent;
    border: 0;
    border-top: 1px solid var(--rule);
    transition: color var(--dur-text) var(--ease);
}

.list-group-item:hover { color: var(--gold-ink); }
.list-group-item.active { color: var(--gold-ink); }

.list-group-flush .list-group-item:first-child { border-top: 0; }

/* ===========================
   Alerts
   =========================== */

.alert {
    padding: var(--sp-3) var(--sp-4);
    margin-bottom: var(--sp-4);
    border: 0;
    border-left: 1px solid var(--ink);
    background: var(--taupe);
    font-size: 0.875rem;
}

.alert-success { border-left-color: #4A6B4A; }
.alert-danger  { border-left-color: #8B3A3A; }
.alert-info    { border-left-color: var(--gold); }

/* ===========================
   Modals — native <dialog>
   =========================== */

dialog.modal {
    width: min(40rem, calc(100vw - 3rem));
    max-height: calc(100vh - 4rem);
    padding: 0;
    border: 1px solid var(--ink);
    background: var(--paper);
    color: var(--ink);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
    overflow: visible;
}

dialog.modal::backdrop {
    background: rgba(26, 26, 26, 0.55);
}

.modal-header,
.modal-footer {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-4);
}

.modal-header {
    justify-content: space-between;
    border-bottom: 1px solid var(--rule);
}

.modal-footer {
    justify-content: flex-end;
    border-top: 1px solid var(--rule);
}

.modal-title {
    font-family: var(--serif);
    font-size: 1.5rem;
    font-weight: 400;
    margin: 0;
}

.modal-body {
    padding: var(--sp-4);
    overflow-y: auto;
    max-height: 60vh;
}

/* ===========================
   Toasts
   =========================== */

.toast-stack {
    position: fixed;
    right: var(--sp-4);
    bottom: var(--sp-4);
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

.toast {
    min-width: 20rem;
    background: var(--paper);
    color: var(--ink);
    border: 1px solid var(--ink);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.toast.show { opacity: 1; transform: none; }

.toast-header {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 0.75rem var(--sp-3);
    border-bottom: 1px solid var(--rule);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
}

.toast-body { padding: var(--sp-3); }

/* ===========================
   Pagination
   =========================== */

.pagination {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    list-style: none;
    padding: 0;
    margin: var(--sp-4) 0;
}

.page-link {
    display: inline-block;
    min-width: 44px;
    padding: 0.6rem 0.8rem;
    text-align: center;
    border: 1px solid var(--rule);
    color: var(--warm-grey);
    font-size: 0.75rem;
    letter-spacing: 0.1em;
    transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.page-link:hover { border-color: var(--ink); color: var(--ink); }

.page-item.active .page-link { border-color: var(--gold); color: var(--gold-ink); }
.page-item.disabled .page-link { opacity: 0.4; pointer-events: none; }

/* ===========================
   Auth card
   =========================== */

.auth-card {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-5);
    min-height: 70vh;
    justify-content: center;
    max-width: 30rem;
    margin-inline: auto;
}

.auth-card > .card { width: 100%; }
.auth-card-logo :is(svg, img) { max-height: 3rem; width: auto; }

/* ===========================================================
   Check-in desk — editorial, on a landscape tablet.

   Deliberate deviations from the design system, and why:
   - Motion here is 150ms, not 500ms. Cinematic timing is for a reader
     with time. This is an operator with a queue: a Confirm button that
     takes half a second to acknowledge reads as a dropped tap, and staff
     double-tap. Everything else on the site keeps the slow easing.
   - Section padding is compact, not py-32. A landscape tablet is ~768px
     tall; generous air here means scrolling to reach a participant.
   - Gridlines are hidden. They add architecture to an editorial page and
     visual noise to a dense operational grid.
   - Type scale is restrained. Serif names, but no text-9xl at a door.
   The palette, hairlines, 0px radii, tracked labels and gold accent
   all still apply, so it reads as the same publication.
   =========================================================== */

.kiosk-container .gridlines,
body.kiosk .gridlines { display: none; }

/* 48px is the accessible floor; 52 is comfortable for a stranger's finger. */
.btn-touch { min-height: 52px; }

.kiosk-container .form-control,
.kiosk-container .form-select { min-height: 48px; }

/* Operators get immediate feedback. */
.kiosk-container .btn,
.kiosk-container .form-control,
.kiosk-container .form-select,
.kiosk-container .attendee-card {
    transition-duration: 150ms;
}

.kiosk-container .btn-primary::before { transition-duration: 150ms; }

/* --- Command bar: full-bleed, owns the entire top zone --- */

/* The bar spans the viewport with 50vw margins; clip the scrollbar sliver.
   `clip` (not `hidden`) so no scroll container is created and sticky survives. */
body.kiosk { overflow-x: clip; }

.checkin-bar {
    position: sticky;
    top: 0;
    z-index: 20;
    /* Full bleed. Previously the paper background stopped at the container's
       content edge, so cards scrolled past its gutters and the bar read as a
       floating strip. Margin pulls to the viewport edges; padding restores
       the content to the container's alignment. */
    margin-inline: calc(50% - 50vw);
    padding-inline: calc(50vw - 50%);
    /* Cancels the kiosk body's 60px offset: the bar owns that zone now,
       and the layout's fixed Back button sits ON the bar, not above it. */
    margin-top: -60px;
    padding-top: 0.75rem;
    padding-bottom: 0.85rem;
    margin-bottom: var(--sp-4);
    background: var(--paper);
    border-bottom: 1px solid var(--ink);
}

/* Event name on its own row, stats + actions stacked beneath it. */
.checkin-bar-top {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-bottom: 0.75rem;
}

.checkin-title {
    font-family: var(--serif);
    font-size: 1.5rem;
    line-height: 1;
    margin: 0;
}

/* Event identity, centred across the full header width. Ellipsis is fully
   reliable on horizontal text (unlike the vertical-writing-mode version
   this replaced); the full name is still on the title tooltip. */
.checkin-event-label {
    margin: 0 auto;
    max-width: 24rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    text-align: center;
    color: var(--warm-grey);
}

/* Masthead flourish beneath the name: two hairlines flanking a single gold
   mark, the one place on this page gold is spent as pure ornament. */
.checkin-event-rule {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
}

.checkin-event-rule-line {
    width: 1.75rem;
    height: 1px;
    background: var(--ink);
}

.checkin-event-rule-mark {
    width: 5px;
    height: 5px;
    flex: 0 0 auto;
    background: var(--gold);
    transform: rotate(45deg);
}

/* Stats (left) and actions (right) share the row beneath the name. */
.checkin-bar-controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
}

/* Reserves room for the layout's fixed Back button (ends ~125px in). Only
   this row needs it — the event name above centres on the full width. */
@media (min-width: 700px) {
    .checkin-bar-controls { padding-left: 6.5rem; }
}

.checkin-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
}

.sync-pill {
    font-size: 0.625rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.sync-pill.is-paused { color: var(--gold-ink); }

/* --- Search + filters: one row; search takes the width --- */

.checkin-controls {
    position: relative;
    display: flex;
    align-items: stretch;
    gap: var(--sp-3);
}

.search-field { position: relative; flex: 1 1 auto; }

.checkin-bar .search-input {
    min-height: 56px;
    padding-left: 2.25rem;
    padding-right: 3rem;
    font-size: 1.0625rem;
    border-bottom-width: 1px;
}

.search-input::-webkit-search-cancel-button { display: none; }

.search-icon {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    color: var(--warm-grey);
    pointer-events: none;
}

.search-clear {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border: 0;
    background: transparent;
    color: var(--warm-grey);
    cursor: pointer;
    transition: color 150ms var(--ease);
}

.search-clear:hover { color: var(--gold-ink); }

/* --- Filters: summary sits beside search; panel drops as a sheet --- */

.filters { margin: 0; display: flex; }

.filters > summary {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    list-style: none;
    cursor: pointer;
    min-height: 56px;
    height: 100%;
    padding: 0 1.25rem;
    border: 1px solid var(--ink);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink);
    white-space: nowrap;
}

.filters > summary::-webkit-details-marker { display: none; }
.filters[open] > summary { background: var(--ink); color: var(--paper); }

.filter-active-dot {
    width: 6px;
    height: 6px;
    background: var(--gold);
}

/* The open panel overlays the grid instead of pushing it down,
   so the bar's height — and the participant list — never jumps. */
.filters-grid {
    position: absolute;
    top: calc(100% + 0.75rem);
    left: 0;
    right: 0;
    z-index: 30;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sp-4);
    margin: 0;
    padding: var(--sp-4);
    background: var(--paper);
    border: 1px solid var(--ink);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}

.filters-reset { display: flex; align-items: flex-end; }

/* --- Counters, inline in the bar --- */

.stat-row {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    padding: 0;
}

.stat { display: flex; align-items: baseline; gap: 0.5rem; }

.stat-value {
    font-family: var(--serif);
    font-size: 1.0625rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.stat-label {
    font-size: 0.625rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

.result-count {
    font-size: 0.6875rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--warm-grey);
    margin-bottom: var(--sp-3);
}

/* --- Participant grid --- */

.attendee-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: var(--sp-4);
}

/* .card is display:flex, which would beat the [hidden] UA rule. */
.attendee-card[hidden] { display: none !important; }

/* Deviation from the top-rule-only card: at 114 cards in a dense grid,
   line-only cards merge into one surface. Each participant must read as
   a discrete box at a glance, so these get a full border and a faint
   surface lift off the paper. */
.attendee-card {
    padding: var(--sp-3) var(--sp-3) var(--sp-3);
    border: 1px solid rgba(26, 26, 26, 0.3);
    border-top: 1px solid var(--ink);
    background-color: rgba(255, 255, 255, 0.55);
    gap: 0.5rem;
}

.attendee-card:hover { background-color: rgba(235, 229, 222, 0.4); }

/* A checked-in group recedes and sinks below everyone still waiting — the
   grid stays sorted to what staff needs to act on. Grid items honour `order`
   the same as flex items; alphabetical order is preserved within each group
   since ties keep DOM order. */
.attendee-card { order: 0; }
.attendee-card.is-complete { order: 1; opacity: 0.55; }
.attendee-card.is-partial { border-top-width: 3px; border-top-color: var(--gold); }

.attendee-name {
    font-family: var(--serif);
    font-size: 1.25rem;
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: -0.01em;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.3em;
}

.attendee-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    min-height: 1.6rem;
}

.attendee-facts {
    display: flex;
    flex-wrap: wrap;
    row-gap: 0.5rem;
    column-gap: var(--sp-4);
    padding: var(--sp-3) 0;
    border-top: 1px solid var(--rule-soft);
    border-bottom: 1px solid var(--rule-soft);
}

.fact { display: flex; flex-direction: column; gap: 0.25rem; justify-content: flex-end; }

.fact-label {
    font-size: 0.5625rem;
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--warm-grey);
}

.fact-value {
    font-family: var(--serif);
    font-size: 1.25rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* Table dominates the strip via placement, not a larger font — table
   and batch read at the same size. */
.fact-table { padding-right: var(--sp-4); border-right: 1px solid var(--rule); }



.fact-pax { margin-left: auto; }

.fact-of { font-family: var(--sans); font-size: 0.75rem; color: var(--warm-grey); }

/* Category + VIP badges in the confirm dialog sit side by side. */
.confirm-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Award recipients get the one gold fill on the page. Ink on gold: 8.3:1. */
.badge-award {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--ink);
}

/* Escort-to-holding-room: same weight as the award chip, bordeaux so the
   two statuses can't be confused. White on #8B3A3A: 7.6:1. */
.badge-holding {
    background: #8B3A3A;
    border-color: #8B3A3A;
    color: var(--on-dark);
}

/* The instruction staff must act on before seating the guest. */
.confirm-holding {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0 0 var(--sp-4);
    padding: 0.85rem var(--sp-3);
    background: #8B3A3A;
    color: var(--on-dark);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.15em;
    text-transform: uppercase;
}

/* In the dialog, table and batch are what staff reads out; pax is bookkeeping. */
.confirm-facts .fact-pax .fact-value {
    font-size: 1.125rem;
    color: var(--warm-grey);
}

.attendee-actions {
    display: flex;
    gap: var(--sp-2);
    margin-top: auto;
    padding-top: var(--sp-3);
}

.attendee-primary { flex: 1 1 auto; padding-inline: 1rem; }
.attendee-history { flex: 0 0 52px; padding: 0; }

/* --- Confirm dialog: wide, never tall --- */

.modal-checkin { width: min(44rem, calc(100vw - 3rem)); }

.checkin-confirm {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: var(--sp-5);
    align-items: center;
}

.confirm-name {
    font-family: var(--serif);
    font-size: 2.25rem;
    line-height: 1.05;
    margin: 0 0 var(--sp-2);
}

.confirm-remarks { margin: 0; color: var(--warm-grey); font-size: 0.875rem; }

.confirm-facts {
    display: flex;
    justify-content: space-around;
    gap: var(--sp-3);
    padding: var(--sp-4);
    border: 1px solid var(--rule);
}

.confirm-facts .fact { align-items: center; }
.confirm-facts .fact-value { font-size: 2rem; }

.confirm-actions { gap: var(--sp-3); }
.confirm-submit { flex: 1 1 auto; }
.confirm-actions .btn-light { flex: 0 0 9rem; }

/* --- Empty state --- */

.empty-state {
    text-align: center;
    padding: var(--sp-6) var(--sp-3);
    color: var(--warm-grey);
}

.empty-state i { font-size: 1.5rem; margin-bottom: var(--sp-3); display: block; }

/* --- Landscape tablet: wide screen, short viewport --- */

@media (min-width: 900px) and (max-height: 900px) {
    .checkin-title { font-size: 1.375rem; }
    .checkin-bar { padding-top: var(--sp-2); }
}

@media (max-width: 899.98px) {
    /* .checkin-bar-top already stacks name-then-controls; below this width
       the controls row also wraps, so stats and actions don't get squeezed. */
    .checkin-event-label { max-width: none; }
    .checkin-bar-controls { flex-wrap: wrap; padding-left: 0; }
    .checkin-bar .stat-row { width: 100%; gap: var(--sp-4); }
    .filters-grid { grid-template-columns: repeat(2, 1fr); }
    .checkin-confirm { grid-template-columns: 1fr; }
    .btn-label { display: none; }
    .attendee-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
}

/* A hover-lift on a touch screen reads as a stuck button. */
@media (hover: none) {
    .btn-primary:hover::before { transform: translateX(-100%); }
    .btn:hover { background-color: transparent; color: var(--ink); }
    .btn-primary:hover { background-color: var(--ink); color: var(--on-dark); }
    .btn:active { opacity: 0.7; }
    .card:hover { background-color: transparent; }
}

/* ===========================
   Dashboard (events index)
   =========================== */

.dash-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: var(--sp-3);
    margin-bottom: var(--sp-5);
}

.dash-header h1 { margin: 0; }

.dash-header-actions {
    display: flex;
    gap: var(--sp-2);
    flex-shrink: 0;
}

.event-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--sp-4) var(--sp-5);
}

@media (min-width: 768px) and (max-width: 1023.98px) {
    .event-grid { grid-template-columns: repeat(2, 1fr); }
}

.event-card {
    border: 1px solid var(--rule);
    padding: var(--sp-4);
    height: 100%;
}

.event-card .card-body { display: flex; flex-direction: column; flex: 1; padding: 0; }

.event-card-actions {
    display: flex;
    gap: var(--sp-2);
    margin-top: auto;
    padding-top: var(--sp-2);
}

.empty-state {
    text-align: center;
    padding: var(--sp-6) 0;
}

.empty-state .lede { max-width: none; margin-inline: auto var(--sp-4); }

/* ===========================
   Motion preferences
   =========================== */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation: none !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
    /* Colour still changes; transforms do not. */
    .btn-primary::before { transform: translateX(0); opacity: 0; }
    .btn-primary:hover::before { opacity: 1; }
}
