/* assets/css/style.css */
/* EasyShow Premium Obsidian & Glassmorphic Design System */

:root {
    /* The default palette is dark, so the browser's own parts -- scrollbars,
       date pickers, autofill -- are dark too. The light and system themes
       below override it with their own color-scheme. */
    color-scheme: dark;

    /* RGB Definitions for translucency */
    --bg-base-rgb: 6, 9, 19;
    --bg-surface-rgb: 15, 19, 34;
    --bg-card-rgb: 20, 26, 46;
    --bg-overlay-rgb: 29, 36, 63;
    
    --accent-primary-rgb: 255, 122, 0;
    
    --text-primary-rgb: 243, 244, 246;
    --text-secondary-rgb: 156, 163, 175;
    --text-muted-rgb: 107, 114, 128;
    
    --border-color-rgb: 30, 37, 64;
    --border-highlight-rgb: 42, 51, 91;
    
    --color-my-dogs-rgb: 239, 68, 68;
    --color-important-rgb: 245, 158, 11;
    --color-orders-rgb: 59, 130, 246;
    --color-friends-rgb: 16, 185, 129;

    /* Color Palette */
    --bg-base: #060913;          /* Deep dark obsidian */
    --bg-surface: #0F1322;       /* Midnight blue-gray surface */
    --bg-card: #141A2E;          /* Muted card background */
    --bg-overlay: #1D243F;       /* Highlight overlays */
    --bg-tab-panel: #04050a;     /* Lists tab panel, a shade deeper than the page (SHOW-151) */
    
    --accent-primary: #FF7A00;   /* Premium Vibrant Orange */
    --accent-glow: rgba(255, 122, 0, 0.8);
    /* The orange used as the colour of text, and of a focus ring. Equal to the
       accent here; an accent theme moves them (SHOW-129). */
    --accent-text: var(--accent-primary);
    --focus-ring: var(--accent-primary);
    /* Orange text that WCAG counts as large (bold from 18.66px). Light Contrast
       and Tinted move it to a brighter orange than --accent-text (SHOW-131). */
    --accent-text-large: var(--accent-text);
    /* Section headings (H2): the same ink as the page, 1.25rem (SHOW-127). */
    --section-heading-color: var(--text-primary);
    --section-heading-now: var(--accent-text);
    --section-heading-size: 1.25rem;

    /* Halls after the first, which keeps the accent (DIM-812). */
    --hall-2: #16A34A;           /* green */
    --hall-3: #3B82F6;           /* blue */
    --hall-4: #A855F7;           /* violet */
    
    --text-primary: #F3F4F6;     /* Bright gray */
    --text-secondary: #9CA3AF;   /* Muted gray */
    --text-unlinked: #959CA9;    /* A name with nothing to open (Dimas, 2026-10-20) */
    --text-muted: #6B7280;       /* Darker muted gray */
    
    --border-color: #1E2540;     /* Sharp clean borders */
    --border-highlight: #2A335B; /* Accent borders */

    /* Fields you type into. Their own shade rather than a darker copy of the
       page: #060913 inside #0F1322 was barely there, and a field that does not
       read as a field is one nobody taps. */
    --bg-input: #232B52;
    --bg-control: #232B52;        /* buttons and panels that sit beside fields: not a field itself */
    --border-input: #434E86;

    /* Stacking layers. Anything positioned should pick one of these rather
       than inventing a number, so page content can never rise above the
       sticky header the way an open autocomplete list once did. */
    /* Height of the sticky header. Anything that sticks inside the page has to
       park below it, so the offset lives here instead of being guessed twice. */
    --header-height: 4.125rem;
    /* The navigation strip is the brand orange (Dimas, 2026-10-27, SHOW-43). */
    --nav-progress: var(--accent-primary);

    --z-content: 5;      /* in-page positioned elements */
    --z-popover: 50;     /* dropdowns and autocomplete lists */
    --z-chrome: 200;     /* sticky header and bottom navigation */
    --z-modal: 1000;     /* modal overlays */
    --z-notice: 9999;    /* toasts and the pull-to-refresh indicator */
    
    /* List priority colors */
    --color-my-dogs: #EF4444;    /* Coral Red */
    --color-important: #F59E0B;  /* Amber Orange */
    --color-orders: #3B82F6;     /* Electric Blue */
    --color-friends: #10B981;    /* Emerald Green */
    
    /* Typography */
    --font-display: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-body: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    
    /* Effects */
    --radius-sm: 8px;
    --radius-md: 14px;
    --radius-lg: 20px;
    --shadow-premium: 0 10px 30px -10px rgba(0, 0, 0, 0.7);
    --transition-premium: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);

    /* The faintest possible lift off the background: hovered rows, striped
       tables, a secondary button under the cursor. It has to invert with the
       theme -- white at 2% is invisible on a white page, and that is a hover
       state and a table stripe silently disappearing rather than a colour
       being slightly off. */
    --tint-subtle: rgba(255, 255, 255, 0.03);
    --tint-subtle-strong: rgba(255, 255, 255, 0.05);
}

/*
 * The light palette.
 *
 * Only the variables are redefined -- nothing below this block knows which
 * theme it is painted in, which is the whole reason 950-odd rules could be
 * given a second palette without being touched. Written once and applied
 * twice: explicitly when the reader chose light, and through
 * prefers-color-scheme when they chose to follow the device.
 *
 * The accent does not change. It is the brand, it carries enough contrast on
 * both grounds, and an orange that shifted with the theme would read as two
 * different products.
 */
:root[data-theme="light"],
:root[data-theme="system"] {
    --bg-base-rgb: 247, 248, 250;
    --bg-surface-rgb: 255, 255, 255;
    --bg-card-rgb: 255, 255, 255;
    --bg-overlay-rgb: 237, 240, 246;

    --text-primary-rgb: 17, 24, 39;
    --text-secondary-rgb: 75, 85, 99;
    --text-muted-rgb: 107, 114, 128;

    --border-color-rgb: 226, 230, 238;
    --border-highlight-rgb: 203, 210, 224;

    --bg-base: #F7F8FA;
    --bg-surface: #FFFFFF;
    --bg-card: #FFFFFF;
    --bg-overlay: #EDF0F6;
    --bg-tab-panel: #EAEDF2;     /* Lists tab panel, a shade deeper than the page (SHOW-151) */

    --text-primary: #111827;
    --text-secondary: #4B5563;
    --text-muted: #6B7280;

    --border-color: #E2E6EE;
    --border-highlight: #CBD2E0;

    --bg-input: #F4F4F4;          /* the one field colour (Dimas, 2026-10-31, SHOW-127) */
    --bg-control: #E4E8F1;
    --border-input: #B4BDCF;

    /* The dark shadow was 70% black lifted off a near-black ground, which on
       white is a smudge. Light needs far less of it to read as raised. */
    --shadow-premium: 0 8px 24px -12px rgba(17, 24, 39, 0.18);

    --tint-subtle: rgba(17, 24, 39, 0.035);
    --tint-subtle-strong: rgba(17, 24, 39, 0.06);
}

/* Chosen light, and meant it: this must win even where the device says dark. */
:root[data-theme="light"] {
    color-scheme: light;
}

/* Following the device. The variables above are the light half, so the dark
   half is simply the defaults from :root, put back when the device asks. */
:root[data-theme="system"] {
    color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="system"] {
        --bg-base-rgb: 6, 9, 19;
        --bg-surface-rgb: 15, 19, 34;
        --bg-card-rgb: 20, 26, 46;
        --bg-overlay-rgb: 29, 36, 63;

        --text-primary-rgb: 243, 244, 246;
        --text-secondary-rgb: 156, 163, 175;
        --text-muted-rgb: 107, 114, 128;

        --border-color-rgb: 30, 37, 64;
        --border-highlight-rgb: 42, 51, 91;

        --bg-base: #060913;
        --bg-surface: #0F1322;
        --bg-card: #141A2E;
        --bg-overlay: #1D243F;
        --bg-tab-panel: #04050a;     /* Lists tab panel, a shade deeper than the page (SHOW-151) */

        --text-primary: #F3F4F6;
        --text-secondary: #9CA3AF;
        --text-muted: #6B7280;

        --border-color: #1E2540;
        --border-highlight: #2A335B;

        --bg-input: #232B52;
        --bg-control: #232B52;
        --border-input: #434E86;

        --shadow-premium: 0 10px 30px -10px rgba(0, 0, 0, 0.7);

        --tint-subtle: rgba(255, 255, 255, 0.03);
        --tint-subtle-strong: rgba(255, 255, 255, 0.05);
    }
}

/* The document itself never scrolls sideways. body alone is not enough: with a
   fixed overlay open, the horizontal scroll a phone offered belonged to the
   root element, which is what made the dashboard slide left and right behind
   an open dialog.

   clip, not hidden: `hidden` makes this element a scroll container, and a
   sticky descendant sticks to that container rather than to the viewport — it
   unstuck the site header the moment it was added. `clip` refuses the scroll
   without creating the container, so the header keeps its perch. */
html {
    overflow-x: clip;
}

/*
 * Interface size.
 *
 * Three sets, chosen in Settings > Appearance and printed on <html> as
 * data-scale. Nothing below this block knows which set it is drawn at: sizes
 * and spacing are written in rem, so moving the root font size moves type and
 * padding together, which is what "a larger interface" has to mean -- type
 * alone grown inside unchanged boxes is a cramped page, not a bigger one.
 *
 * Compact is the original and is exactly 100%: every rem below was converted
 * from the pixel value it already had, so a reader who never opens this
 * setting sees the app unchanged to the pixel.
 *
 * A percentage rather than a pixel size, because the root font size a reader
 * set in their own browser is a preference too, and multiplying it keeps that
 * honoured. The two larger steps are deliberately modest -- roughly an eighth
 * and a quarter -- since a phone at a ringside has a fixed width, and past
 * that a table stops fitting rather than becoming easier to read.
 */
:root,
:root[data-scale="compact"] {
    font-size: 100%;
}

/* No text inflation by the phone's browser: iOS enlarged the tracker's type
   (blocks of text) and left the ring tables alone, so the same 0.95rem read a
   size apart (Dimas, 2026-11-01, SHOW-127). Sizes come from data-scale only. */
:root {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

:root[data-scale="medium"] {
    font-size: 112.5%;
}

:root[data-scale="large"] {
    font-size: 125%;
}

/* Base resets */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/*input, textarea, select, .btn-premium {*/
/*    box-sizing: border-box;*/
/*}*/

/* The browser hides [hidden] from its own stylesheet, and ANY author `display`
   beats it — so a class like .expo-schedule-pill (display: inline-flex) left
   hidden pills on screen: every show showed "Source changed" while the totals,
   read from the same elements in JS, said zero. Author-level, so it wins. */
[hidden] {
    display: none !important;
}

body {
    background-color: var(--bg-base);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 0.95rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    padding-bottom: 5.625rem;
    /* clip, not hidden, for the same reason as on html above: hidden makes body
       a scroll container and the sticky header then sticks to body instead of
       to the viewport — which is to say it does not stick at all. */
    overflow-x: clip;
    overscroll-behavior-y: none;
}

/* Every link is the brand colour unless a component gives it another
   (Dimas, 2026-10-20). A bare element selector, so any class still wins; and
   an author rule beats the browser's own, so its blue and visited purple —
   which showed on the judge profile — never reach a page. */
a { color: var(--accent-text); }

/* Header & Branding */
header {
    background-color: rgba(var(--bg-base-rgb), 0.8);
    backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--border-color);
    padding: 0 1.5rem;
    /* Fixed height so --header-height is the truth for sticky offsets below. */
    height: var(--header-height);
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: var(--z-chrome);
}

/*
 * The masthead does not take part in the interface size.
 *
 * Everything else in the app is written in rem so that compact, medium and
 * large move type and spacing together -- but the mark, the name beside it and
 * the version under that are the app's signature, not text anybody reads a
 * timetable from. Grown a quarter they crowd out the header without helping
 * anyone, so this corner is pinned in pixels on purpose. The values are the
 * rem they replaced, at the compact root: nothing moves at the default size.
 */
.brand {
    font-family: var(--font-display);
    font-size: 22.4px;
    font-weight: 800;
    letter-spacing: -0.03em;
    color: var(--text-primary);
    display: inline-flex;
    align-items: center;
    gap: 0;
    text-decoration: none;
}

.brand-logo {
    display: block;
    width: 65px;
    height: 65px;
    object-fit: contain;
}

.header-brand {
    display: flex;
    align-items: center;
}

.header-brand-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.brand span {
    /* The logo's own colour, in every theme and accent: "Show" is never re-tinted (Dimas, 2026-10-31). */
    color: var(--accent-primary);
}

.brand:hover {
    filter: drop-shadow(0 0 8px var(--accent-glow));
}

.clock-panel {
    text-align: right;
    padding-left: 0.4375rem;
    line-height: 1.2;
}

.header-tools {
    align-items: center;
    display: flex;
    gap: 0;
}

.account-avatar {
    align-items: center;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 50%;
    color: var(--text-primary);
    display: flex;
    flex: 0 0 auto;
    justify-content: center;
    height: 40px;
    margin: 0 0 0 10px;
    /* The unread badge sits on the rim and must be allowed out; the photograph
       is cropped by its own radius instead of by the frame's overflow. */
    overflow: visible;
    position: relative;
    /* A link: the initial inside it would otherwise be underlined (SHOW-59). */
    text-decoration: none;
    width: 40px;
}

.account-avatar svg {
    fill: none;
    height: 19px;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-width: 1.7;
    width: 19px;
}

/* display: flex above would otherwise beat the hidden attribute: the
   notifications bell beside the avatar is hidden until app.js shows it (DIM-813). */
.account-avatar[hidden] { display: none; }
.account-push-off { color: var(--accent-text); }

.account-avatar:hover {
    border-color: var(--accent-primary);
    color: var(--accent-text);
}

.account-avatar:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.guest-account-links {
    align-items: center;
    display: flex;
    gap: 0.5rem;
}

.guest-account-links a {
    border: 1px solid var(--border-color);
    border-radius: 7px;
    color: var(--text-primary);
    font: 700 .72rem var(--font-display);
    padding: 0.4375rem 0.625rem;
    text-decoration: none;
    text-transform: uppercase;
}

.guest-account-links a:last-child {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: #fff;
    position: relative;
}

/* An invisible 44px-tall tap area (SHOW-127): the link looks and lays out as before. */
.guest-account-links a:last-child::before {
    content: "";
    height: 44px;
    left: 0;
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
}

/* The migration ledger. A list of files where the interesting column is the
   one that says whether it ran, so the state is a coloured word next to the
   name rather than something to work out from a date. */
.migration-list { display: grid; gap: 0; }
.migration-row { align-items: start; border-top: 1px solid var(--border-color); display: grid; gap: 1rem; grid-template-columns: 1fr auto; padding: 0.75rem 0; }
.migration-row:first-child { border-top: 0; }
.migration-name strong { display: block; font: 600 .88rem var(--font-display); overflow-wrap: anywhere; }
.migration-name small { color: var(--text-muted); display: block; font-size: .74rem; margin-top: 2px; }
.migration-status { font-weight: 700; }
.migration-ok .migration-status { color: var(--color-friends); }
.migration-adopted .migration-status { color: var(--text-secondary); }
.migration-pending .migration-status { color: var(--color-important); }
.migration-failed .migration-status { color: var(--color-my-dogs); }
.migration-running .migration-status { color: var(--color-orders); }
.migration-changed { color: var(--color-important); }
.migration-output { margin-top: 6px; }
.migration-output summary { color: var(--text-secondary); cursor: pointer; font-size: .74rem; }
.migration-output pre { background: var(--bg-base); border-radius: var(--radius-sm); font-size: .72rem; margin-top: 6px; overflow-x: auto; padding: 0.625rem; white-space: pre-wrap; }
.migration-row .btn-premium { padding: 0.5rem 1rem; width: auto; }

@media (max-width: 560px) {
    .migration-row { grid-template-columns: 1fr; }
    .migration-row .btn-premium { justify-self: start; }
}

/* "+ Create" at the head of the row of kinds on the Lists page (DIM-775):
   the same chip, in the accent colour, so it reads as the action and not as
   one more kind of list. */
.list-create-btn {
    background: rgba(var(--accent-primary-rgb), .12);
    border-color: var(--accent-primary);
    color: var(--accent-text);
    cursor: pointer;
}
.list-create-btn:hover { background: var(--accent-primary); color: var(--bg-base); }
.empty-state .list-create-btn { margin-top: 1rem; }

/* The kind switches on the Lists page. Same chips as the dashboard, but they
   start at the left edge here: they are the page's first choice, not a filter
   tucked against the right of something already on screen. */
.list-type-filter { flex-wrap: wrap; justify-content: flex-start; }
/* The kinds read as the tabs of a panel (SHOW-148): they sit on its top edge and
   the open one joins it. Still plain links to separate pages. The panel is a
   shade deeper than the page, --bg-tab-panel (Dimas, 2026-10-31, SHOW-151,
   after borders alone in SHOW-150); the open tab takes the same colour so it
   hides the panel's top border under it. */
/* Two classes: .tracker-filters comes later in this file and would win back
   its right alignment and 14px gap, which kept the tabs off the panel. */
.tracker-filters.list-type-filter { flex-wrap: nowrap; gap: 0.25rem; justify-content: flex-start; margin-bottom: 0; }
.list-type-filter .tracker-filter {
    background: transparent;
    border: 1px solid var(--border-color);
    border-bottom: 0;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    color: var(--text-muted);
    padding: 0.55rem 1rem;
}
.list-type-filter .tracker-filter.active {
    background: var(--bg-tab-panel);
    border-color: var(--border-color);
    border-top: 2px solid var(--accent-primary);
    color: var(--text-primary);
    margin-bottom: -1px;
    position: relative;
    z-index: 1;
}
.list-tab-panel {
    background: var(--bg-tab-panel);
    border: 1px solid var(--border-color);
    border-radius: 0 var(--radius-md) var(--radius-md) var(--radius-md);
    margin-bottom: 14px;
    padding: 1rem;
}
.list-tab-panel > :first-child { margin-top: 0; }
/* A little air between Create list and the first list under it (Dimas, 2026-10-31). */
.list-tab-panel > .list-type-actions { margin-bottom: 0.75rem; }
.list-tab-panel > :last-child,
.list-tab-panel > :last-child > :last-child { margin-bottom: 0; }
@media (max-width: 600px) {
    .list-type-filter .tracker-filter { flex: 1 1 0; font-size: .72rem; justify-content: center; min-width: 0; padding: 0.55rem 0.25rem; text-align: center; }
    .list-tab-panel { padding: 0.75rem; }
}
.list-choose-hint { color: var(--text-muted); font-size: .85rem; margin: 14px 0; }
/* Pencil and bin on the end of a row of a list. */
.list-item-actions { display: flex; flex: 0 0 auto; gap: 0.5rem; }
.list-item-actions form { margin: 0; }
/* A breed switched off in this list (SHOW-149): kept, greyed, its eye shut. */
.list-item-row.is-off .breed-item-meta { opacity: .45; }
.list-item-row .list-item-eye-off { display: none; }
.list-item-row .list-item-eye-on { display: inline-flex; }
.list-item-row.is-off .list-item-eye-on { display: none; }
.list-item-row.is-off .list-item-eye-off { display: inline-flex; }
/* On a phone (no mouse) the pencil, eye and bin are one dots button with a menu,
   and a long press on the row opens it too (Dimas, 2026-11-01, SHOW-165). */
.list-item-more { display: none; flex: 0 0 auto; }
.list-item-more .bulk-actions-menu { left: auto; right: 0; }
.list-item-more .bulk-menu-item { text-align: left; }
@media (hover: none) {
    .list-item-actions { display: none; }
    .list-item-more { display: block; }
    .list-item-row[data-hold-menu] { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
}

.list-pill-show { font-size: .72rem; font-weight: 400; margin-left: auto; opacity: .6; text-align: right; white-space: nowrap; }

/* A list on the Lists page (Dimas, 2026-10-20, DIM-793): the name a size up and
   white, the comment under it in the colour it had, and the list's Change
   menu as a pencil at the right that shows on hover or after a long press. */
.list-pill-wrap { position: relative; }
.list-pill-wrap:hover, .list-pill-wrap:focus-within, .list-pill-wrap.is-holding { z-index: 2; }
/* The one with its menu open stays above the next ones: iOS gives a tapped
   button no focus, so :focus-within alone left the menu under the next list (SHOW-165). */
.list-pill-wrap:has([aria-expanded="true"]),
.list-item-row:has([aria-expanded="true"]) { position: relative; z-index: 3; }
.list-pill-wrap .list-pill { -webkit-touch-callout: none; -webkit-user-select: none; min-height: 3.4225rem; padding-bottom: 0.25rem; padding-left: 0.75rem; padding-right: 3.25rem; padding-top: 0.25rem; user-select: none; } /* tighter cards (Dimas, 2026-10-31, SHOW-157); a list without a comment as tall as one with it (SHOW-127) */
.list-pill-text { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; }
.list-pill-name { color: var(--text-primary); font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-pill-text .list-pill-show { margin-left: 0; text-align: left; white-space: normal; }
.list-pill-wrap .list-pill-actions { opacity: 0; pointer-events: none; position: absolute; right: 3.125rem; top: 50%; transform: translateY(-50%); transition: opacity .15s ease; }
.list-pill-wrap:hover .list-pill-actions,
.list-pill-wrap:focus-within .list-pill-actions,
.list-pill-wrap.is-holding .list-pill-actions,
.list-pill-actions:has([aria-expanded="true"]) { opacity: 1; pointer-events: auto; }
.list-pill-edit { align-items: center; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: inline-flex; height: 2.25rem; justify-content: center; width: 2.25rem; }
.list-pill-edit:hover { border-color: var(--accent-primary); color: var(--text-primary); }
/* Square: the menu trigger's own width: auto must not stretch it into a pill. */
/* The eye beside the pencil (DIM-796): shown with the pencil on hover; on a
   hidden list it stays, shut, and the list is greyed. */
/* The eye is the last button on the right, the pencil before it (Dimas, 2026-10-31, SHOW-152). */
.list-pill-eye-form { margin: 0; opacity: 0; pointer-events: none; position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%); transition: opacity .15s ease; }
.list-pill-wrap:hover .list-pill-eye-form,
.list-pill-wrap:focus-within .list-pill-eye-form,
.list-pill-wrap.is-hidden-list .list-pill-eye-form { opacity: 1; pointer-events: auto; }
.list-pill-eye { align-items: center; aspect-ratio: 1; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 8px; box-sizing: border-box; color: var(--text-secondary); cursor: pointer; display: inline-flex; height: 2.25rem; justify-content: center; padding: 0; width: 2.25rem; }
.list-pill-eye:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.list-pill-eye .action-icon { height: 1rem; width: 1rem; }
.list-pill-wrap .list-pill { padding-right: 5.5rem; }
/* The Share button (SHOW-139) left of the eye; on Favorites, alone at the pencil's place. */
.list-pill-share { align-items: center; aspect-ratio: 1; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 8px; box-sizing: border-box; color: var(--text-secondary); cursor: pointer; display: inline-flex; height: 2.25rem; justify-content: center; opacity: 0; padding: 0; pointer-events: none; position: absolute; right: 5.75rem; top: 50%; transform: translateY(-50%); transition: opacity .15s ease; width: 2.25rem; }
.list-pill-share.is-favorites { right: 0.5rem; }
.list-pill-wrap:hover .list-pill-share,
.list-pill-wrap:focus-within .list-pill-share { opacity: 1; pointer-events: auto; }
.list-pill-share:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.list-pill-share .action-icon { height: 1rem; width: 1rem; }
.list-pill-wrap.has-share .list-pill { padding-right: 8.25rem; }
.list-pill-wrap.is-hidden-list .list-pill { opacity: .5; }
.list-pill-wrap.is-hidden-list .list-pill-name { color: var(--text-secondary); }

/* No mouse (Dimas, 2026-11-01, SHOW-165): a tap leaves a phone's :hover and
   :focus-within stuck on the list, so nothing here depends on them. The pencil
   becomes a dots button, always visible and the only button on the pill: Share
   and the eye are in its menu, and a hidden list is known by its .5 opacity.
   A long press opens the same menu. Favorites has no menu and shows nothing. */
.list-pill-edit-pencil, .list-pill-edit-dots { display: inline-flex; }
.list-pill-edit-dots { display: none; }
@media (hover: none) {
    .list-pill-edit-pencil { display: none; }
    .list-pill-edit-dots { display: inline-flex; }
    .list-pill-wrap .list-pill-actions { opacity: 1; pointer-events: auto; right: 0.5rem; }
    .list-pill-wrap .list-pill-eye-form,
    .list-pill-wrap:hover .list-pill-eye-form,
    .list-pill-wrap:focus-within .list-pill-eye-form,
    .list-pill-wrap.is-hidden-list .list-pill-eye-form { opacity: 0; pointer-events: none; }
    .list-pill-wrap .list-pill-share,
    .list-pill-wrap:hover .list-pill-share,
    .list-pill-wrap:focus-within .list-pill-share { opacity: 0; pointer-events: none; }
    .list-pill-wrap:not(.has-share) .list-pill { padding-right: 1rem; }
    .list-pill-wrap.has-share .list-pill,
    .list-pill-wrap.is-hidden-list.has-share .list-pill { padding-right: 3.25rem; }
}
.list-pill-wrap .list-pill-edit { aspect-ratio: 1; box-sizing: border-box; flex: 0 0 auto; height: 2.25rem; min-width: 0; padding: 0; width: 2.25rem; }
.list-pill-edit .action-icon { height: 1rem; width: 1rem; }
.list-pill-actions .bulk-actions-menu form { margin: 0; }
.list-pill-actions a.bulk-menu-item { color: var(--text-primary); text-decoration: none; }
.list-pill-actions .bulk-actions-menu form .bulk-menu-item { width: 100%; }
.schedule-list-filter { flex-wrap: wrap; margin-bottom: 12px; }
.schedule-list-filter-note { align-self: center; color: var(--accent-text); font: 700 .72rem var(--font-display); letter-spacing: .04em; text-transform: uppercase; }

/* Translations. The index is a phone book: a code per line, a column per
   language, and a blank column where a translation is missing -- that gap is
   the whole point of the page, so it is spotted without reading anything. */
.translation-search { align-items: stretch; display: flex; gap: 0.625rem; margin-bottom: 10px; max-width: 560px; }
.translation-search .input-field { flex: 1 1 auto; margin: 0; min-width: 0; }
/* .btn-premium is a full-width block by default, which on one row with a field
   eats the field. Beside an input it is only as wide as its own word. */
.translation-search .btn-premium { flex: 0 0 auto; padding: 0.75rem 1.375rem; white-space: nowrap; width: auto; }
.translation-index { margin-top: 24px; }
.translation-letter { display: grid; gap: 0 1.5rem; grid-template-columns: 56px 1fr; margin-bottom: 18px; }
/* The letter follows its own group down and stops at its end, so you always
   know which letter you are inside of. align-self keeps it its own height --
   a stretched grid item fills its area and has nowhere to stick to -- and the
   grid area is the group, which is what confines it to its own block.
   --header-height is the fixed header it must park under; it is a token
   precisely so this offset is not guessed a second time. */
.translation-letter h2 {
    align-self: start;
    color: var(--text-muted);
    font: 700 2rem var(--font-display);
    margin: 0;
    position: sticky;
    text-align: center;
    top: calc(var(--header-height) + 12px);
    z-index: var(--z-content);
}
.translation-rows { display: grid; }
.translation-row { align-items: baseline; border-radius: var(--radius-sm); display: grid; gap: 1rem; grid-template-columns: 1fr auto; padding: 0.375rem 0.5rem; text-decoration: none; }
.translation-row:hover { background: var(--bg-overlay); }
.translation-name { display: grid; gap: 0.0625rem; min-width: 0; }
.translation-text { color: var(--accent-text); font-size: .92rem; overflow-wrap: anywhere; }
.translation-text.untranslated { color: var(--color-important); font-style: italic; }
.translation-code { color: var(--text-muted); font-size: .7rem; letter-spacing: .02em; overflow-wrap: anywhere; }
.translation-editing-code { color: var(--text-muted); font-size: .78rem; margin: -8px 0 18px; }
.translation-langs { display: grid; gap: 0.25rem; grid-template-columns: repeat(5, 28px); }
.translation-lang-mark { color: var(--text-secondary); font-size: .78rem; text-align: center; }
.translation-lang-mark.missing { border-bottom: 1px solid rgba(var(--color-important-rgb),.35); }

.translation-editor { display: grid; gap: 0.75rem; }
.translation-field { align-items: start; display: grid; gap: 0.625rem; grid-template-columns: 32px 1fr; }
.translation-field .input-field { margin: 0; }
.translation-lang { color: var(--text-muted); font: 700 .72rem var(--font-display); padding-top: 0.625rem; }
.translation-field.missing .input-field { border-color: rgba(var(--color-important-rgb),.5); }
.translation-field.missing .translation-lang { color: var(--color-important); }
.translation-flag { align-items: start; display: grid; gap: 0.625rem; grid-template-columns: 18px 1fr; }
.translation-flag small { color: var(--text-muted); display: block; font-size: .76rem; }
.translation-delete { align-items: center; display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 18px; }
.translation-delete .settings-intro { flex: 1; margin: 0; min-width: 240px; }

@media (max-width: 560px) {
    .translation-letter { grid-template-columns: 34px 1fr; gap: 0 0.625rem; }
    .translation-row { grid-template-columns: 1fr; gap: 0.125rem; }
}

.language-choices { display: flex; flex-wrap: wrap; gap: 0.625rem; margin: 18px 0; }
.language-choice { align-items: center; background: var(--bg-base); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-secondary); cursor: pointer; display: flex; font: inherit; gap: 0.625rem; padding: 0.75rem 1rem; transition: var(--transition-premium); }
.language-choice:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.language-choice.active { border-color: var(--accent-primary); color: var(--text-primary); }
.language-choice-code { color: var(--accent-text); font: 800 .72rem var(--font-display); }
.language-choice:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* Theme picker. Same shape as the language choices, plus a swatch: the three
   options differ in how they look, so showing it beats describing it. The
   swatches are painted in literal colours on purpose -- a dark swatch has to
   stay dark while the page around it is light, or it illustrates nothing. */
.theme-choices { display: flex; flex-direction: column; gap: 0.625rem; margin: 18px 0; }
.theme-choice { align-items: center; background: var(--bg-base); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-secondary); cursor: pointer; display: flex; font: inherit; gap: 0.75rem; padding: 0.75rem 1rem; text-align: left; transition: var(--transition-premium); width: 100%; }
.theme-choice:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.theme-choice.active { border-color: var(--accent-primary); color: var(--text-primary); }
.theme-choice:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.theme-choice-text { display: flex; flex-direction: column; gap: 0.125rem; }
.theme-choice-text strong { color: var(--text-primary); font: 700 .9rem var(--font-display); }
.theme-choice-text small { color: var(--text-muted); font-size: .76rem; }
.theme-choice-swatch { border: 1px solid var(--border-highlight); border-radius: 50%; flex: 0 0 auto; height: 26px; width: 26px; }
/* Settings → Notifications: one table, the notice on the left and a column of
   toggles each for Pop-up and Email (DIM-813, Dimas 2026-10-21). */
.notify-table { display: flex; flex-direction: column; gap: 0.5rem; margin: 18px 0 4px; }
.notify-row { align-items: center; display: grid; gap: 0.75rem; grid-template-columns: minmax(0, 1fr) 72px 72px; }
.notify-row:not(.notify-head) { background: var(--bg-base); border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 0.75rem 0.5rem 0.75rem 1rem; }
.notify-head { color: var(--text-muted); font-size: .68rem; font-weight: 700; letter-spacing: .02em; line-height: 1.2; padding: 0 0.5rem 0 1rem; text-transform: uppercase; }
/* A column title wider than its column wraps onto a second line instead of
   running into its neighbour, as the Russian "Всплывающие" did (DIM-813). */
.notify-head span, .notify-cell { display: flex; justify-content: center; min-width: 0; text-align: center; }
.notify-minutes { background: var(--bg-elevated, var(--bg-base)); border: 1px solid var(--accent-primary); border-radius: 6px; color: var(--text-primary); font: inherit; font-weight: 700; margin: 0 .15rem; padding: .06em .12em; text-align: center; width: 3.2em; }
/* The orange border shows it is a field to type into; the grey one was lost on the
   dark card (Dimas, 2026-10-30, SHOW-97). */
.notify-minutes:focus { box-shadow: 0 0 0 2px rgba(var(--accent-primary-rgb), .25); outline: none; }
.notify-switch { appearance: none; background: var(--border-color); border-radius: 999px; cursor: pointer; flex: 0 0 auto; height: 24px; margin: 0; position: relative; transition: background .2s; width: 42px; }
.notify-switch::before { background: #fff; border-radius: 50%; content: ""; height: 18px; left: 3px; position: absolute; top: 3px; transition: transform .2s; width: 18px; }
.notify-switch:checked { background: var(--accent-primary); }
.notify-switch:checked::before { transform: translateX(18px); }
.notify-switch:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.push-device { align-items: center; display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 12px 0 4px; }
.push-device-state { margin: 0; }
/* Notification history list (Dimas, 2026-11-01, SHOW-127). */
.push-history { list-style: none; margin: 12px 0 0; padding: 0; }
.push-history li { border-top: 1px solid var(--border-color); padding: 0.6rem 0; }
.push-history li:first-child { border-top: 0; }
.push-history-item { color: inherit; display: block; text-decoration: none; }
a.push-history-item:hover strong { text-decoration: underline; }
.push-history-time { color: var(--text-secondary); display: block; font-size: .8rem; }
.push-history-item strong { display: block; }
.push-history-body { display: block; overflow-wrap: anywhere; }
.notify-saving { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 999px; bottom: calc(84px + env(safe-area-inset-bottom)); color: var(--text-primary); font-size: .85rem; left: 50%; margin: 0; padding: 0.45rem 1rem; position: fixed; transform: translateX(-50%); z-index: 50; }
.theme-swatch-dark { background: #0F1322; }
.theme-swatch-light { background: #F7F8FA; }
.theme-swatch-system { background: linear-gradient(135deg, #0F1322 0 50%, #F7F8FA 50% 100%); }

/* The size choices reuse the theme rows; the swatch is replaced by an "Aa"
   drawn at the size that choice actually gives, so the row is a sample rather
   than a description of one. Sizes in em against the row's own text, so the
   samples stay in the same proportion whichever set is currently on. */
.scale-choice-sample { align-items: center; color: var(--text-primary); display: flex; flex: 0 0 auto; font-family: var(--font-display); font-weight: 700; justify-content: center; line-height: 1; width: 1.75rem; }
/* Steps drawn further apart than the real scales, so the difference reads at a glance (Dimas, 2026-10-31, SHOW-127). */
.scale-sample-compact { font-size: .9rem; }
.scale-sample-medium { font-size: 1.35rem; }
.scale-sample-large { font-size: 1.9rem; }
/* Appearance: each choice a vertical card, three to a row; on a phone only the
   sample and the name, the hint would wrap to five lines (Dimas, 2026-10-31, SHOW-127). */
.theme-choices[data-appearance-grid] { display: grid; gap: 0.625rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.theme-choices[data-appearance-grid] .theme-choice { align-items: center; flex-direction: column; gap: 0.625rem; justify-content: flex-start; padding: 1rem 0.625rem 0.875rem; text-align: center; }
.theme-choices[data-appearance-grid] .theme-choice-text { align-items: center; }
.theme-choices[data-appearance-grid] .theme-choice-swatch { height: 44px; width: 44px; }
.theme-choices[data-appearance-grid] .scale-choice-sample { height: 2.75rem; width: auto; }
.theme-choices[data-appearance-grid] .accent-choice-sample { height: 2.75rem; }
@media (max-width: 520px) { .theme-choices[data-appearance-grid] .theme-choice-text small { display: none; } .theme-choices[data-appearance-grid] .theme-choice { padding: 0.875rem 0.375rem 0.75rem; } }

/* Language switcher. A <details> rather than a scripted menu: it belongs in the
   header for a guest who has not loaded anything yet, and the five entries are
   plain links carrying ?lang, so it works with no JavaScript at all. */
.lang-switch {
    position: relative;
}

.lang-switch > summary {
    border: 1px solid var(--border-color);
    border-radius: 7px;
    color: var(--text-secondary);
    cursor: pointer;
    font: 700 .72rem var(--font-display);
    list-style: none;
    margin: 0 8px;
    padding: 0.4375rem 0.5625rem;
    user-select: none;
}

.lang-switch > summary::-webkit-details-marker { display: none; }

.lang-switch > summary:hover,
.lang-switch[open] > summary {
    border-color: var(--border-highlight);
    color: var(--text-primary);
}

.lang-switch > summary:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.lang-switch-menu {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, .4);
    display: flex;
    flex-direction: column;
    min-width: 160px;
    overflow: hidden;
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: var(--z-popover);
}

.lang-switch-menu a {
    color: var(--text-secondary);
    font-size: .85rem;
    padding: 0.625rem 0.875rem;
    text-decoration: none;
    white-space: nowrap;
}

.lang-switch-menu a:hover {
    background: var(--bg-overlay);
    color: var(--text-primary);
}

.lang-switch-menu a.active {
    color: var(--accent-text);
    font-weight: 600;
}

.clock-time {
    font-family: var(--font-display);
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--accent-text-large);
    letter-spacing: -0.02em;
}

.blink-colon {
    animation: blink-colon 1s step-end infinite;
}

@keyframes blink-colon {
    50% { opacity: 0; }
}

.clock-date {
    font-size: 0.75rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* Main Container */
.container {
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    padding: 1.25rem;
    /* Clear the fixed bottom nav so the last card is never trapped under it. */
    padding-bottom: calc(5rem + env(safe-area-inset-bottom, 0px));
}
@media (max-width: 500px) {
    .container {
        padding: 0.625rem;
        padding-bottom: calc(4.625rem + env(safe-area-inset-bottom, 0px));
    }
    header {
        padding: 0 0.625rem 0 0.125rem;
    }
}



/* Profile settings (SHOW-59): Google and Microsoft side by side where there is
   room. The password card is headed by a section header of its own. */
.profile-providers { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.profile-providers .profile-google-link { margin: 0; }

/* One heading system (Dimas, 2026-10-31, SHOW-127, variant B). The tag says the
   level, one scale says how it looks: H1 the page title, H2 a section, H3 a
   card or a group, H4 a small label. A class that gives a heading a look of its
   own (a ring table, a modal, the auth card) wins over these by specificity. */
h1, h2, h3, h4 {
    color: var(--text-primary);
    font-family: var(--font-display);
    line-height: 1.2;
}
h1 { font-size: 1.75rem; font-weight: 800; letter-spacing: -0.035em; }
h2 { font-size: 1.25rem; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
h3 { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
h4 { color: var(--text-secondary); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }

/* The page title where it is not a bare h1: sentence case, no rule line. */
.page-title { margin: 0.25rem 0 0.5rem; }
.info-card .page-title { margin-top: 0; }
.settings-section-bar .page-title,
.judge-profile-heading .page-title { margin: 0; }

/* h2s that keep their own look: the sentence-case ones that were never
   capitals, the dashboard's banners and the ring tables. */
.dashboard-banner-title, .passkey-nudge-title, .changes-day-title, .empty-state h2, .empty-state h3,
.schedule-own-head, .schedule-ring-table h2, .judge-card h2, .translation-letter h2 {
    letter-spacing: normal;
    text-transform: none;
}
.dashboard-banner-title, .passkey-nudge-title, .changes-day-title { font-weight: 700; }
/* The empty state's title, as the browser sized it before the scale (1.5em of the card's text). */
.empty-state h2, .empty-state h3 { font-size: 1.425rem; font-weight: 700; }

/* H4, the small label above a group. Used on any tag the outline needs. */
.build-notes-heading, .usage-subheading {
    color: var(--text-secondary);
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Visible to a screen reader and to a search engine, not to the eye: the h1 of
   a page whose first thing on screen is a list. */
.visually-hidden {
    border: 0;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

/* Section Header Typography: the H2 look on any tag. */
.section-header,
.settings-group-title {
    font-family: var(--font-display);
    font-size: var(--section-heading-size);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.2;
    color: var(--section-heading-color);
    margin: 32px 0 16px 0;
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.section-header::after,
.settings-group-title::after {
    content: '';
    flex: 1;
    height: 1px;
    background-color: var(--border-color);
}

/* One style for a text link in running text (Dimas, 2026-10-31): the accent
   text colour and a permanent 2px orange underline, 3px under the text. Buttons
   (.btn-premium), tabs, nav and cards that are links are not in the list. New
   links in prose take .text-link rather than a colour of their own. */
.text-link,
:is(.dashboard-banner p, .schedule-empty-state p, .info-contacts-name, .info-contacts-links, .auth-agree, .consent-bar,
    .auth-google-note, .auth-switch, .assistant-all-shows) a:not(.btn-premium),
.auth-forgot {
    color: var(--accent-text);
    text-decoration: underline;
    text-decoration-color: #FF7A00;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
}
.text-link:hover,
:is(.dashboard-banner p, .schedule-empty-state p, .info-contacts-name, .info-contacts-links, .auth-agree, .consent-bar,
    .auth-google-note, .auth-switch, .assistant-all-shows) a:not(.btn-premium):hover,
.auth-forgot:hover {
    text-decoration-thickness: 3px;
}

/* Active Show Pill */
.active-show-bar {
    background: linear-gradient(90deg, var(--bg-surface) 0%, var(--bg-card) 100%);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    margin-bottom: 24px;
    box-shadow: var(--shadow-premium);
    overflow: hidden;
}

/* The whole card opens the show where its name is a link (Dimas, 2026-10-29,
   SHOW-55): the link's box is stretched over the card, and the settings
   cog stands above it. A show without a timetable has a span, so nothing
   stretches. */
.show-card,
.active-show-header { position: relative; }
.show-card a.show-card-name::after,
.active-show-header a.show-card-name::after { content: ""; inset: 0; position: absolute; }
.show-card .show-settings-link,
.active-show-header .show-settings-link { position: relative; z-index: 1; }

.active-show-header {
    padding: 0.875rem 1.25rem;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

/* The dashboard pill and a row of the shows list are the same card: a mark, a
   name, a venue, a tag. They were two families of class saying it twice, which
   is why the mark and the pin had to be added to each of them separately and
   why line-height: 1 landed on one of the two names. The pill keeps only what
   is really its own -- the bar, the header row, the countdown and the day
   buttons -- and everything inside it is .show-card-*.

   The info block still has to be the one that grows: the header is
   space-between, and without this the name and the countdown drift apart. */
.active-show-header .show-card-info { flex: 1 1 auto; }

.active-show-countdown {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
    white-space: nowrap;
    line-height: 1.2;
}

.active-show-countdown-value {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.4rem;
    color: var(--accent-text-large);
}

.active-show-countdown-label {
    font-weight: 400;
    font-size: 1rem;
    color: var(--text-secondary);
}

/* The "now" tag in the countdown's place while the rings run. The badge the
   ring rows wear, a size up: it stands alone on the right, not beside a name.
   Two classes, because .schedule-now-badge is declared further down. */
.schedule-now-badge.active-show-now {
    margin-left: 0;
    font-size: 0.8rem;
    padding: 0.25rem 0.5rem;
}

.active-show-dates {
    display: flex;
    width: 100%;
    border-top: 1px solid var(--border-color);
}

.active-show-date-btn {
    flex: 1;
    text-align: center;
    padding: 0.625rem;
    font-size: 0.85rem;
    font-family: var(--font-display);
    text-decoration: none;
    font-weight: 700;
    color: var(--text-secondary);
    background-color: var(--bg-overlay);
    border-right: 1px solid var(--border-color);
    transition: var(--transition-premium);
}

.active-show-date-btn:last-child {
    border-right: none;
}

.active-show-date-btn:hover {
    background-color: var(--bg-surface);
    color: var(--text-primary);
}

.active-show-date-btn.active {
    background-color: var(--accent-primary);
    color: white;
}

/* A show whose ring schedule has not been imported yet is not dimmed: the name
   is a span rather than a link, and "No timetable" beside it says why. At 65%
   the dashboard card read paler than the same show on the shows list
   (Dimas, 2026-10-29, SHOW-55). */

/* The agreement at sign-up, and the cookie question in the welcome dialog. Both
   are a paragraph the reader has to be able to read before answering, so the
   control sits beside the text rather than above a wall of it. */
.auth-agree { align-items: flex-start; display: flex; font-weight: 400; gap: 0.625rem; line-height: 1.35; }
/* .settings-form input is display:block;width:100%, which a checkbox has no
   business inheriting: at full width it pushed the sentence beside it clean off
   the right of the screen. Overridden by element, not by class, so a checkbox
   added to this label later behaves the same. */
/* 20px, not the browser's 13px: a box that small next to a sentence is hard to hit
   on a phone (Dimas, 2026-10-30, SHOW-115). */
.auth-agree input[type="checkbox"] { accent-color: var(--accent-primary); flex: 0 0 auto; height: 1.25rem; margin: 0; width: 1.25rem; }
.auth-agree span { flex: 1 1 auto; font-size: .84rem; min-width: 0; }
.auth-agree + .auth-agree { margin-top: .5rem; }
/* Belongs to the field above it, so it takes back most of the form's 1rem gap. */
.settings-form .auth-field-hint { color: var(--text-muted); display: block; font-size: .75rem; margin: .375rem 0 .875rem; }

/* The cookie question, on every page. It sits above the bottom navigation
   rather than over the header — the header carries the brand, the clock and the
   account — and above the raised dashboard circle, the same clearance the
   offline banner takes. Not fixed to the very bottom, because that is where the
   navigation is and a reader's thumb is already there. */
.consent-bar {
    background: var(--bg-card);
    border-top: 1px solid var(--border-color);
    bottom: calc(4.75rem + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -12px 32px rgba(0,0,0,.45);
    left: 0;
    margin: 0 auto;
    max-width: 800px;
    padding: 0.875rem 1rem;
    position: fixed;
    right: 0;
    z-index: var(--z-notice);
}

.consent-bar[hidden] { display: none !important; }
/* The same question, asked again on the cookies page so an answer can be taken
   back. Hidden until the client has read the stored answer. */
.consent-choice { border-top: 1px solid var(--border-color); margin-top: 14px; padding-top: 0.875rem; }
.consent-choice[hidden] { display: none !important; }
.consent-choice-state { color: var(--text-primary); font: 600 .84rem var(--font-display); margin: 0; }
.consent-bar-text { color: var(--text-secondary); font-size: .82rem; line-height: 1.4; margin: 0; }
.consent-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 12px; }
.consent-actions .btn-premium { flex: 1 1 auto; width: auto; }

@media (min-width: 560px) {
    .consent-bar { border: 1px solid var(--border-color); border-radius: var(--radius-md); left: 16px; right: 16px; }
}

.info-subheading { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; margin: 16px 0 6px; text-transform: none; }

/* List Selector: one list per line, top to bottom (Dimas, 2026-10-19,
   DIM-775). It was a row that scrolled sideways, and a list past the edge of
   the screen was a list nobody knew they had. */
.list-pills {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin: 1rem 0 1.25rem;
}

.list-pill {
    padding: 0.75rem 1rem;
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    font-family: var(--font-display);
    font-weight: 600;
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background-color: var(--bg-surface);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    transition: var(--transition-premium);
    min-width: 0;
}

.list-pill:hover {
    color: var(--text-primary);
    border-color: var(--border-highlight);
}

.list-pill.active {
    color: var(--text-primary);
    background-color: var(--bg-card);
    border-color: var(--accent-primary);
}

.list-pill-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: 0 0 auto;
}

/* Cards & Layout */
.card-premium {
    background-color: var(--bg-surface);
    /*border: 1px solid var(--border-color);*/
    border-radius: var(--radius-md);
    padding: 0.75rem;
    margin-bottom: 10px;
    box-shadow: var(--shadow-premium);
    transition: var(--transition-premium);
}

/* Hover belongs to a pointer that can hover. On iOS the first tap on an
   element with a hover style is spent producing that hover and the click only
   lands on the second tap, which is why an admin had to tap a ring row twice to
   open the time picker. Touch never enters the hover state now, so the first
   tap is the click. */
/* Only a card that opens something lifts under the pointer: a show card whose
   name is a link, which the whole card stretches (Dimas, 2026-10-29, SHOW-64).
   A card that is not a link does not answer the mouse at all. */
@media (hover: hover) {
    .card-premium:has(a.show-card-name):hover {
        border-color: var(--border-highlight);
        transform: translateY(-2px);
    }
}

/* Settings subpages */
.settings-group-title:first-of-type { margin-top: 8px; }
.settings-menu { display: grid; gap: 0.625rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.settings-menu-item { align-items: center; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: var(--radius-md); color: var(--text-primary); display: grid; gap: 0.875rem; grid-template-columns: 42px 1fr auto; padding: 0.5rem 0.5rem; text-decoration: none; transition: var(--transition-premium); }
.settings-menu-item:hover { border-color: var(--accent-primary); transform: translateY(-2px); }
.settings-menu-item:focus-visible, .btn-premium:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.settings-menu-mark { align-items: center; background: rgba(var(--accent-primary-rgb),.12); border: 1px solid rgba(var(--accent-primary-rgb),.25); border-radius: 50%; color: var(--accent-text); display: flex; flex: 0 0 42px; height: 42px; justify-content: center; width: 42px; }
/* A drawing rather than the initial of the row's English title, which said
   nothing in the other four languages and collided with itself in English. */
.settings-menu-icon { display: block; height: 20px; width: 20px; }
/* The inbox's unread count, at the right before the arrow, drawn like the
   Settings tab's badge (Dimas, 2026-11-01, SHOW-127). */
/* A fourth column for it, so the arrow stays on the row (SHOW-127). */
.settings-menu-item:has(> .settings-menu-count) { grid-template-columns: 42px 1fr auto auto; }
.settings-menu-count { align-items: center; background: var(--color-my-dogs); border-radius: 999px; color: #fff; display: inline-flex; flex: none; font: 700 .75rem/1 var(--font-display); height: 1.375rem; justify-content: center; min-width: 1.375rem; padding: 0 .4em; }
.settings-menu-item strong { display: block; font: 700 .95rem var(--font-display); }
.settings-menu-item small { color: var(--text-muted); display: block; font-size: .75rem; margin-top: 3px; }
.settings-menu-arrow { color: var(--text-muted); font-size: 1.1rem; transition: transform .2s ease; }
/* The contacts card at the end of Info (Dimas, 2026-10-30). */
.info-contacts-name { display: flex; flex-direction: column; gap: 0.125rem; margin: 0 0 0.75rem; }
.info-contacts-name strong { color: var(--text-primary); font: 700 1.375rem var(--font-display); line-height: 1.25; }
.info-contacts-name span { color: var(--text-secondary); }
.info-contacts-links { display: grid; gap: 0.375rem; list-style: none; margin: 0; padding: 0; }
.info-contacts-label { color: var(--text-muted); }
.info-contacts-links a { overflow-wrap: anywhere; }
.signout-checks { display: grid; gap: 0.625rem; list-style: none; margin: 0; padding: 0; }
.signout-checks li { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.625rem 0.875rem; }
.signout-checks strong { display: block; margin-top: 2px; overflow-wrap: anywhere; }
/* The text on the left, Add a passkey on the right (Dimas, 2026-10-30). */
.signout-checks .signout-check-todo { align-items: center; border-color: rgba(var(--accent-primary-rgb),.45); display: flex; flex-wrap: wrap; gap: 0.625rem 0.75rem; justify-content: space-between; }
.signout-checks .signout-passkey-add { display: inline-flex; gap: 0.5rem; margin-left: auto; padding: 0.5rem 1rem; text-decoration: none; width: auto; }
.signout-passkey-icon { height: 18px; width: 18px; }
.reload-page .settings-intro { margin-top: 0; }
.reload-choose { font-weight: 600; margin: 0 0 0.25rem; }
.reload-option { align-items: center; cursor: pointer; display: flex; gap: 0.75rem; min-height: 44px; }
.reload-option input[type="checkbox"] { accent-color: var(--accent-primary); flex: 0 0 auto; height: 1.25rem; margin: 0; width: 1.25rem; }
.reload-page form .btn-premium { margin-top: 0.75rem; }
.reload-page form .btn-premium:disabled { cursor: not-allowed; opacity: 0.5; }
.reload-kept { color: var(--text-muted); margin: 0 0 1rem; }
/* Fixed colours on purpose: the same alarm in light and dark theme (Dimas, 2026-10-31, SHOW-127). */
.reload-warning { align-items: flex-start; background: linear-gradient(90deg, #FEE2E2, #FEF3C7); border: 2px solid #DC2626; border-radius: var(--radius-sm); color: #111827; display: none; gap: 0.75rem; margin: 0.25rem 0 0.5rem 2rem; padding: 0.625rem 0.875rem; }
.reload-page form:has(input[name="cache"]:checked) .reload-warning { display: flex; }
.reload-warning p { margin: 0; }
.reload-warning-time { color: #B91C1C; font-weight: 700; }
.reload-warning-icon { color: #DC2626; flex: 0 0 auto; height: 1.5rem; width: 1.5rem; }
.reload-error { color: var(--text-primary); font-weight: 600; margin: 0.75rem 0 0; }
/* The screen is locked while the erase runs (SHOW-127). */
.reload-overlay { align-items: center; background: rgba(0, 0, 0, .72); display: flex; inset: 0; justify-content: center; position: fixed; z-index: var(--z-notice); }
.reload-overlay-box { align-items: center; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); display: flex; flex-direction: column; gap: 1rem; max-width: 80vw; padding: 1.5rem 2rem; text-align: center; }
.reload-overlay-box:focus { outline: none; }
.reload-spinner { animation: reload-spin 0.9s linear infinite; border: 4px solid var(--border-color); border-radius: 50%; border-top-color: var(--accent-primary); height: 3rem; width: 3rem; }
@keyframes reload-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .reload-spinner { animation: none; border-color: var(--accent-primary); border-style: dotted; } }
.signout-decided { color: var(--text-muted); margin: 0 0 0.75rem; }
/* Narrower on purpose, 90% of the column, centred (Dimas, 2026-10-30). */
.signout-decision { margin-left: auto; margin-right: auto; width: 90%; }
.signout-actions { align-items: center; display: flex; gap: 0.75rem; justify-content: space-between; }
.signout-actions .btn-premium { width: auto; }
.signout-account, .signout-reload { text-decoration: none; }
.signout-actions .btn-premium, .signout-checks .signout-account { align-items: center; display: inline-flex; gap: 0.5rem; }
/* The address on the left, Account settings on the right (Dimas, 2026-10-31). */
.signout-checks .signout-check-email { align-items: center; display: flex; flex-wrap: wrap; gap: 0.625rem 0.75rem; justify-content: space-between; }
.signout-checks .signout-account { margin-left: auto; padding: 0.5rem 1rem; width: auto; }
/* Solid red, the strongest button on the page (Dimas, 2026-10-30). */
.signout-form .signout-confirm { background: var(--color-my-dogs); border: 1px solid var(--color-my-dogs); color: #fff; font-weight: 600; width: auto; }
.signout-form .signout-confirm:hover { background: #DC2626; border-color: #DC2626; }
/* Sign out (SHOW-141): the tile in the circle's old pink, the circle solid red, the icon white. */
.settings-menu-signout { background: rgba(var(--color-my-dogs-rgb),.12); border-color: rgba(var(--color-my-dogs-rgb),.3); }
.settings-menu-signout .settings-menu-mark { background: var(--color-my-dogs); border-color: var(--color-my-dogs); color: #fff; }
.settings-menu-signout:hover { border-color: var(--color-my-dogs); }
.settings-menu-steward .settings-menu-mark { background: rgba(var(--color-friends-rgb),.12); border-color: rgba(var(--color-friends-rgb),.3); color: var(--color-friends); }
.settings-menu-item:hover .settings-menu-arrow { color: var(--accent-text); transform: translateX(3px); }
/* The breadcrumb trail at the top of every page the bottom navigation does not
   reach (SHOW-189; it replaced the single Back link). One line at every width:
   the first crumb (the tab) never shrinks, the middle ones give way first and end
   in an ellipsis, the last one -- the page -- keeps as much as it can. */
.breadcrumbs { font: 700 .78rem var(--font-display); margin: 2px 0 14px; }
.breadcrumbs ol { align-items: center; display: flex; flex-wrap: nowrap; gap: 0.25rem; list-style: none; margin: 0; padding: 0; }
.breadcrumbs li { align-items: center; display: flex; flex: 0 4 auto; gap: 0.25rem; min-width: 0; }
.breadcrumbs li:first-child { flex: 0 0 auto; }
.breadcrumbs li:last-child { flex: 0 1 auto; }
.breadcrumbs a, .breadcrumbs span { overflow: hidden; padding: 4px 0; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; }
.breadcrumbs a { color: var(--text-secondary); }
.breadcrumbs a:hover { color: var(--accent-text); }
.breadcrumbs a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.breadcrumbs span[aria-current] { color: var(--text-primary); }
.breadcrumb-sep { color: var(--text-secondary); flex: 0 0 auto; height: 14px; opacity: .7; width: 14px; }
.settings-back-icon { height: 15px; width: 15px; }
.settings-intro { color: var(--text-secondary); margin-bottom: 20px; }
.settings-form { display: grid; gap: 1rem; }
.settings-form label { color: var(--text-primary); font-family: var(--font-display); font-weight: 600; }
.settings-form small { color: var(--text-muted); display: block; font-family: var(--font-body); font-size: .76rem; font-weight: 400; }
.settings-form input, .settings-form select { display: block; margin-top: 6px; width: 100%; }
.settings-form .btn-premium { justify-self: start; margin-top: 4px; }
.avatar-field { align-items: center; display: grid; gap: 0.875rem; grid-template-columns: 64px 1fr; }
.avatar-preview-wrap { border-radius: 50%; cursor: pointer; display: block; height: 64px; transition: var(--transition-premium); width: 64px; }
.avatar-preview-wrap:hover { box-shadow: 0 0 0 3px rgba(var(--accent-primary-rgb), .35); }
.avatar-controls { display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.avatar-title { color: var(--text-primary); font-family: var(--font-display); font-weight: 600; }
.settings-form .avatar-pick { cursor: pointer; font-size: .78rem; padding: 0.5rem 0.875rem; width: auto; }
/* The picker opens from the photo or the button; the field itself stays out
   of sight but reachable, so the keyboard still tabs to it. */
.settings-form .avatar-file-input { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; white-space: nowrap; width: 1px; }
.avatar-controls:focus-within .avatar-pick { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.profile-avatar { background: var(--bg-base); border: 1px solid var(--border-highlight); border-radius: 50%; display: block; height: 64px; object-fit: cover; width: 64px; }
.profile-avatar-placeholder { align-items: center; color: var(--accent-text); display: flex; font: 800 1.35rem var(--font-display); justify-content: center; }
.settings-form .profile-save-status { color: var(--text-muted); margin-top: -0.5rem; }
.settings-form .profile-save-status[hidden] { display: none; }
.settings-form .profile-save-status.profile-save-error { color: var(--color-my-dogs); }
.avatar-crop-modal { max-width: 420px; }
.avatar-crop-modal .modal-header small { color: var(--text-muted); display: block; font-size: .73rem; margin-top: 3px; }
.avatar-crop-body { align-items: center; display: flex; flex-direction: column; }
.avatar-crop-stage { background: #050812; cursor: grab; height: min(300px, calc(100vw - 80px)); overflow: hidden; position: relative; touch-action: none; user-select: none; width: min(300px, calc(100vw - 80px)); }
.avatar-crop-stage.dragging { cursor: grabbing; }
.avatar-crop-stage > img { max-width: none; pointer-events: none; position: absolute; user-select: none; }
.avatar-crop-shade { border: 2px solid rgba(255,255,255,.9); border-radius: 50%; box-shadow: 0 0 0 999px rgba(var(--bg-base-rgb),.68), inset 0 0 0 1px rgba(var(--bg-base-rgb),.35); inset: 0; margin: 8px; pointer-events: none; position: absolute; }
.avatar-zoom-label { color: var(--text-secondary); font: 700 .75rem var(--font-display); margin-top: 18px; width: 100%; }
.avatar-zoom-label input { accent-color: var(--accent-primary); display: block; margin-top: 8px; width: 100%; }
.avatar-crop-actions { display: flex; gap: 0.5rem; margin-top: 20px; width: 100%; }
.avatar-crop-actions .btn-premium { flex: 1; font-size: .76rem; padding: 0.625rem 0.75rem; }
/* Right after the word "Email", not floated to the far side (Dimas, 2026-10-29, SHOW-59). */
.email-status { border-radius: 20px; display: inline-block; font: 700 .66rem var(--font-display); margin-left: .5rem; padding: 0.1875rem 0.5rem; vertical-align: middle; }
.email-status-verified { background: rgba(var(--color-friends-rgb),.12); color: var(--color-friends); }
.email-status-pending { background: rgba(var(--color-important-rgb),.1); color: var(--text-primary); } /* (Dimas, 2026-10-31, SHOW-127) */
.resend-verification { border-top: 1px solid var(--border-color); margin-top: 18px; padding-top: 0.875rem; }
.resend-verification button { background: none; border: 0; color: var(--accent-text); cursor: pointer; font: 700 .78rem var(--font-display); padding: 0; }
.verified-copy { color: var(--color-friends) !important; }
.pending-copy { color: var(--color-important) !important; }
.auth-primary-link { box-sizing: border-box; display: block; margin-top: 18px; text-align: center; text-decoration: none; }
.steward-ring-modal-show { color: var(--text-muted); display: block; font-size: .82rem; font-weight: 400; margin-top: .25rem; }
.steward-ring-hall-card { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 12px; padding: .875rem; }
.steward-ring-hall-card + .steward-ring-hall-card { margin-top: .75rem; }
.steward-ring-hall { font-size: 1.05rem; font-weight: 700; letter-spacing: .04em; margin: 0 0 .625rem; text-transform: uppercase; }
.steward-ring-hall.hall-1 { color: var(--accent-text); }
.steward-ring-hall.hall-2 { color: var(--hall-2); }
.steward-ring-hall.hall-3 { color: var(--hall-3); }
.steward-ring-hall.hall-4 { color: var(--hall-4); }
.steward-ring-picks { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); }
.steward-ring-pick { align-items: flex-start; background: var(--bg-base); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); cursor: pointer; display: flex; flex-direction: column; font: inherit; gap: .125rem; padding: .625rem .75rem; text-align: left; }
.steward-ring-pick strong { font-size: .95rem; }
.steward-ring-pick small { color: var(--text-muted); font-size: .75rem; }
.steward-ring-pick:hover, .steward-ring-pick.is-selected { border-color: var(--accent-primary); }
.steward-offer-banner { align-items: center; background: rgba(var(--accent-primary-rgb), .08); border: 1px solid rgba(var(--accent-primary-rgb), .35); border-radius: var(--radius-sm); display: flex; gap: .75rem 1rem; justify-content: space-between; margin: 0 0 1.25rem; padding: .875rem 1rem; }
.steward-offer-banner > span { display: flex; flex: 1 1 14rem; flex-direction: column; gap: .125rem; min-width: 0; }
.steward-offer-banner strong { color: var(--text-primary); font-size: 1rem; }
.steward-offer-banner small { color: var(--text-secondary); font-size: .82rem; }
.steward-offer-banner .btn-premium { flex: 0 0 auto; width: auto; }
.steward-offer-banner { flex-wrap: wrap; }
.steward-offer-banner > .steward-offer-actions { align-items: center; flex: 0 0 auto; flex-direction: row; gap: .5rem; margin-left: auto; }
/* Not today (SHOW-107): grey, one line, the title small and Enable a small grey
   button; Not today itself goes. The banner stays, so Enable is still a tap away. */
.steward-offer-banner.is-later { background: linear-gradient(270deg, rgba(var(--color-important-rgb), .16), rgba(var(--color-important-rgb), .04)); border-color: var(--border-color); padding: .375rem .75rem; }
.steward-offer-banner.is-later strong { color: var(--text-muted); font-size: .82rem; font-weight: 600; }
.steward-offer-banner.is-later small, .steward-offer-banner.is-later .steward-offer-later { display: none; }
.steward-offer-banner.is-later .btn-premium { background: transparent; border: 1px solid var(--border-color); box-shadow: none; color: var(--text-muted); font-size: .7rem; min-height: 0; padding: .25rem .625rem; }
.settings-card-title { font-family: var(--font-display); font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; margin-bottom: 16px; text-transform: none; }
.settings-data { color: var(--text-secondary); display: grid; gap: 0.5rem 1rem; grid-template-columns: 100px 1fr; }
.settings-data strong { color: var(--text-primary); }
.status-ok, .status-error { border-radius: 20px; display: inline-block; font-size: .78rem; margin-left: 8px; padding: 0.125rem 0.5rem; }
.status-ok { background: rgba(var(--color-friends-rgb),.12); color: var(--color-friends); }
.status-error { background: rgba(var(--color-my-dogs-rgb),.12); color: var(--color-my-dogs); }
.table-status-list { margin-bottom: 20px; }
.table-status-list > div { border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; padding: 0.5625rem 0; }
.settings-warning, .settings-success { border-radius: var(--radius-sm); font-size: .85rem; margin-bottom: 16px; padding: 0.75rem; }
.settings-warning { background: rgba(var(--color-important-rgb),.08); color: var(--text-primary); } /* (Dimas, 2026-10-31, SHOW-127) */
.settings-success { background: rgba(var(--color-friends-rgb),.08); color: var(--color-friends); }
.debug-mode-switch { align-items: center; cursor: pointer; display: flex; gap: 1rem; justify-content: space-between; }
.debug-mode-switch > span { min-width: 0; }
.debug-mode-switch strong, .debug-mode-switch small { display: block; }
.debug-mode-switch strong { color: var(--text-primary); font: 700 .95rem var(--font-display); }
.debug-mode-switch small { color: var(--text-muted); font-size: .75rem; margin-top: 3px; }
.debug-mode-switch input { height: 1px; opacity: 0; position: absolute; width: 1px; }
.debug-mode-switch i { background: var(--bg-base); border: 1px solid var(--border-highlight); border-radius: 20px; flex: 0 0 auto; height: 26px; position: relative; transition: var(--transition-premium); width: 46px; }
.debug-mode-switch i::after { background: var(--text-muted); border-radius: 50%; content: ""; height: 18px; left: 3px; position: absolute; top: 3px; transition: var(--transition-premium); width: 18px; }
.debug-mode-switch input:checked + i { background: rgba(var(--accent-primary-rgb),.2); border-color: var(--accent-primary); }
.debug-mode-switch input:checked + i::after { background: var(--accent-primary); transform: translateX(20px); }
.debug-mode-switch input:focus-visible + i { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.debug-clock-status { background: linear-gradient(90deg, rgba(var(--color-my-dogs-rgb),.2), rgba(var(--color-important-rgb),.14)); border: 1px solid var(--color-my-dogs); border-radius: var(--radius-sm); color: var(--text-primary); margin-bottom: 18px; padding: 0.875rem; } /* (Dimas, 2026-10-31, SHOW-127) */
.debug-clock-status strong, .debug-clock-status > span, .debug-clock-status p > span { display: block; }
.debug-clock-status > span, .debug-clock-status p > span { font-size: .82rem; margin-top: 3px; }
div.debug-clock-status { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; }
div.debug-clock-status p { margin: 0; }
.debug-clock-status-exit { align-items: center; background: transparent; border: 1.5px solid var(--color-important); border-radius: 8px; color: var(--text-primary); cursor: pointer; display: inline-flex; font: 700 .85rem var(--font-display); gap: .3rem; line-height: 1; min-height: 2.25rem; padding: .45rem .8rem; white-space: nowrap; } /* (Dimas, 2026-10-31, SHOW-127) */
.debug-clock-status-exit:hover { background: rgba(var(--color-important-rgb), .18); }
.debug-clock-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
/* The way back again under the form, besides the one on the banner (Dimas, 2026-10-31, SHOW-127). */
.debug-clock-back { gap: .4rem; justify-content: center; margin-top: 1rem; width: 100%; }
.debug-clock-back .action-icon { height: 1.1rem; width: 1.1rem; }
.debug-own-title { border-top: 1px solid var(--border-color); margin-top: 1.25rem; padding-top: 1.25rem; }
.debug-clock-fields { align-items: start; display: grid; gap: .75rem; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.debug-clock-fields label { margin: 0; min-width: 0; }
.debug-clock-fields input, .debug-clock-fields select { box-sizing: border-box; height: 3rem; margin-top: .5rem; min-width: 0; width: 100%; }
/* iOS Safari draws a date or time field its own way: it ignores width: 100%
   and runs past the card's right edge, grows taller than the select beside it
   and centres the value (Dimas, 2026-11-01, SHOW-127). Without the native look
   the field takes the width and height it is given; the picker still opens. */
input[type="date"], input[type="datetime-local"], input[type="time"] { -webkit-appearance: none; appearance: none; max-width: 100%; min-width: 0; text-align: left; }
input[type="date"]::-webkit-date-and-time-value,
input[type="datetime-local"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value { margin: 0; min-height: 1.2em; text-align: left; }
@media (max-width: 480px) { .debug-clock-fields { grid-template-columns: minmax(0, 1fr); } }
.debug-clock-note { color: var(--text-muted); display: block; font-size: .75rem; margin-top: .5rem; }
.debug-clock-actions .btn-premium { flex: 1 1 10rem; }
.debug-show-days { display: flex; flex-direction: column; gap: .5rem; margin: 0 0 1.125rem; }
.debug-show-days-title { font-weight: 600; }
.debug-show-days-hint { color: var(--text-muted); display: block; font-size: .8rem; margin-bottom: .75rem; }
.debug-show-days-group { align-items: center; display: flex; gap: .75rem; }
.debug-show-days-name { color: var(--text-primary); flex: 0 0 10rem; font-size: .875rem; font-weight: 700; }
.debug-show-days-row { display: flex; flex-wrap: wrap; gap: .5rem; }
.debug-show-day { align-items: center; background: var(--bg-base); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); cursor: pointer; display: flex; gap: .625rem; padding: .5rem .75rem .5rem .5rem; text-align: left; }
.debug-show-day-cal { align-items: center; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 6px; display: flex; flex-direction: column; height: 2.75rem; justify-content: center; width: 2.5rem; }
.debug-show-day-cal b { font-size: 1.0625rem; font-weight: 700; line-height: 1; }
.debug-show-day-cal small { color: var(--text-muted); font-size: .6875rem; }
.debug-show-day-text { align-items: flex-start; display: flex; flex-direction: column; gap: .25rem; }
.debug-show-day-text strong { font-size: .8125rem; font-weight: 600; }
.debug-show-day-time { background: rgba(var(--accent-primary-rgb), .15); border-radius: 999px; color: var(--accent-text); font-size: .75rem; font-weight: 600; line-height: 1.4; padding: 0 .5rem; }
.debug-show-day-tag { background: var(--bg-overlay); border: 1px solid var(--border-color); border-radius: 999px; color: var(--text-secondary); font-size: .6875rem; line-height: 1.4; padding: 0 .5rem; }
@media (max-width: 600px) { .debug-show-days-group { align-items: flex-start; flex-direction: column; gap: .375rem; } .debug-show-days-name { flex: none; } }
.debug-show-day.muted, .debug-show-day.muted strong { color: var(--text-secondary); }
.debug-show-day:disabled { cursor: not-allowed; opacity: .6; }
.debug-show-day:not(:disabled):hover { background: var(--bg-overlay); border-color: var(--accent-primary); }
.debug-show-day.is-selected { border-color: var(--accent-primary); box-shadow: inset 0 0 0 1px var(--accent-primary); }
.debug-clock-reset { border-top: 1px solid var(--border-color); margin-top: 18px; padding-top: 1.125rem; }
/* Settings → Profiler (SHOW-127): a mode choice in the Appearance style, then the
   limits in two equal columns; the Hours field exists only in the timed mode. */
.profiler-status { background: var(--bg-base); border: 1px solid var(--border-color); border-left: 4px solid var(--accent-primary); border-radius: var(--radius-sm); color: var(--text-primary); margin-bottom: 18px; padding: 0.875rem 1rem; }
.profiler-status strong, .profiler-status > span { display: block; }
.profiler-status > span { color: var(--text-secondary); font-size: .82rem; margin-top: 3px; }
.profiler-mode { border: 0; display: flex; flex-direction: column; gap: 0.625rem; margin: 0; min-width: 0; padding: 0; }
.profiler-mode .theme-choice { font-weight: 400; }
.profiler-mode .theme-choice:has(input:checked) { border-color: var(--accent-primary); color: var(--text-primary); }
.profiler-mode .theme-choice:has(input:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.settings-form .profiler-mode input[type="radio"] { accent-color: var(--accent-primary); flex: 0 0 auto; margin: 0; width: auto; }
.profiler-fields { align-items: end; display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.profiler-hours { grid-column: 1 / -1; }
.settings-form:has(input[name="always"][value="1"]:checked) .profiler-hours { display: none; }
@media (max-width: 520px) { .profiler-fields { grid-template-columns: 1fr; } }
.profiler-actions { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 18px; }
.profiler-actions .btn-premium { width: auto; }
/* Beside the mark, and pinned with it: see .brand above. */
.debug-clock-tag {
    background: rgba(var(--color-important-rgb), 0.2);
    border: 1px solid rgba(var(--color-important-rgb), 0.4);
    color: var(--text-primary); /* (Dimas, 2026-10-31, SHOW-127) */
    gap: 0.375rem;
    padding: 3px 8px 3px 6px;
    border-radius: var(--radius-sm);
    font-size: 16px;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s;
}
.debug-clock-tag:hover {
    background: rgba(var(--color-important-rgb), 0.3);
}
/* The clock inside the banner: no gap of its own, the banner's colour. */
.debug-clock-tag .clock-panel { color: inherit; padding-left: 0; }
.benefit-banner { align-items: center; background: linear-gradient(110deg, rgba(var(--accent-primary-rgb),.15), var(--bg-surface)); border: 1px solid rgba(var(--accent-primary-rgb),.35); border-radius: var(--radius-md); display: flex; gap: 1.25rem; justify-content: space-between; margin: 16px 0 24px; padding: 1.25rem; }
.benefit-banner strong { color: var(--text-primary); display: block; font: 700 1.05rem var(--font-display); }
.benefit-banner span { color: var(--text-secondary); display: block; font-size: .82rem; margin-top: 2px; }
.benefit-actions { display: flex; flex: 0 0 auto; gap: 0.5rem; }
.benefit-actions .btn-premium { font-size: .72rem; padding: 0.5625rem 0.75rem; text-decoration: none; width: auto; }
.users-layout { display: grid; gap: 1rem; }
.settings-section-bar { align-items: center; display: flex; justify-content: space-between; margin-bottom: 12px; }
.section-header-group { display: flex; flex-direction: column; gap: 0.2rem; }
.settings-section-bar .section-header { margin: 0; }
.settings-section-bar .btn-premium { font-size: .75rem; padding: 0.5625rem 0.8125rem; width: auto; }
.directory-tools { align-items: center; display: flex; gap: 0.5rem; }
/* Two buttons share the right edge of a section bar, so they shrink to fit. */
.btn-compact { font-size: .7rem !important; padding: 0.4375rem 0.6875rem !important; white-space: nowrap; }
/* Stop stands beside the menu rather than inside it, and is only there at all
   while a run is going. */
.breed-toolbar { display: flex; align-items: center; gap: 0.5rem; }
.breed-toolbar > [hidden] { display: none; }
.directory-count { color: var(--text-muted); font: 700 .72rem var(--font-display); text-transform: uppercase; }
.judges-directory { display: grid; gap: 0.75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.judge-card { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: var(--radius-md); box-shadow: var(--shadow-premium); overflow: hidden; }
.judge-card-heading { align-items: center; display: flex; gap: 0.75rem; padding: 1rem; }
.judge-monogram { align-items: center; background: rgba(var(--accent-primary-rgb),.12); border: 1px solid rgba(var(--accent-primary-rgb),.25); border-radius: 50%; color: var(--accent-text); display: flex; flex: 0 0 auto; font: 800 .9rem var(--font-display); height: 42px; justify-content: center; width: 42px; }
.judge-photo { border: 1px solid var(--border-color); border-radius: 50%; flex: 0 0 auto; height: 42px; object-fit: cover; width: 42px; }
.judge-card-identity { flex: 1 1 auto; min-width: 0; }
.judge-card h2 { color: var(--text-primary); font: 700 .95rem var(--font-display); margin: 0; }
.judge-name-link { color: inherit; text-decoration: none; }
.judge-name-link:hover { color: var(--accent-text); }
.judge-name-link:focus-visible { border-radius: 3px; outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.judge-card-heading p { color: var(--text-muted); font-size: .73rem; margin-top: 3px; }
.judge-card-controls { align-items: center; display: flex; gap: 0.375rem; opacity: 0; pointer-events: none; transform: translateX(5px); transition: opacity .18s ease, transform .18s ease; }
.judge-card:hover .judge-card-controls, .judge-card:focus-within .judge-card-controls { opacity: 1; pointer-events: auto; transform: translateX(0); }
.judge-card-controls form { margin: 0; }
.judge-card-controls .btn-premium { font-size: .68rem; padding: 0.4375rem 0.5rem; text-decoration: none; width: auto; }
.judge-show-list { border-top: 1px solid var(--border-color); display: grid; }
.judge-show-list > p { color: var(--text-muted); font-size: .75rem; padding: 0.75rem; }
.judge-show-list a { align-items: center; color: var(--text-secondary); display: flex; font-size: .78rem; gap: 0.75rem; justify-content: space-between; padding: 0.625rem 0.75rem; text-decoration: none; }
.judge-show-list a + a { border-top: 1px solid rgba(var(--border-color-rgb),.7); }
.judge-show-list a:hover { background: var(--bg-card); color: var(--text-primary); }
.judge-show-list strong { font-weight: 600; }
.judge-show-list span { color: var(--text-muted); flex: 0 0 auto; font-size: .7rem; }
.judge-profile-heading { align-items: center; display: flex; gap: 0.875rem; margin-bottom: 18px; }
.judge-profile-heading .judge-monogram { height: 52px; width: 52px; }
.judge-profile-heading .judge-photo { height: 52px; width: 52px; }
.judge-profile-heading form { margin: 0; }
.judge-show-list > div { align-items: center; color: var(--text-secondary); display: flex; font-size: .78rem; gap: 0.75rem; justify-content: space-between; padding: 0.625rem 0.75rem; }
.judge-show-list > div + div { border-top: 1px solid rgba(var(--border-color-rgb),.7); }
.judge-profile-heading p { color: var(--text-muted); font-size: .78rem; margin-top: 4px; }
.judge-edit-layout { align-items: start; display: grid; gap: 1rem; grid-template-columns: minmax(0, 1fr) minmax(280px, .85fr); }
.judge-edit-layout .card-premium { margin-bottom: 0; }
/* Edge to edge inside the card: the negative margin is the card's own padding
   (.card-premium, 0.75rem), or the rules stick out past its sides. */
.judge-history-card .judge-show-list { margin: 0 -0.75rem -0.75rem; }
.judge-fci-facts { display: grid; font-size: .8rem; gap: 0.375rem 1rem; grid-template-columns: max-content minmax(0, 1fr); margin: 0.75rem 0 0; }
.judge-fci-facts dt { color: var(--text-muted); }
.judge-fci-facts dd { margin: 0; }
.judge-fci-groups { border-top: 1px solid var(--border-color); display: grid; font-size: .8rem; margin: 0.75rem -0.75rem -0.75rem; }
.judge-fci-group { border-bottom: 1px solid rgba(var(--border-color-rgb),.7); padding: 0.625rem 0.75rem; }
.judge-fci-group:last-child { border-bottom: 0; }
div.judge-fci-group, .judge-fci-group summary { align-items: baseline; display: flex; gap: 0.75rem; justify-content: space-between; }
.judge-fci-group summary { cursor: pointer; list-style: none; }
.judge-fci-group summary::-webkit-details-marker { display: none; }
.judge-fci-group > span, .judge-fci-group summary > span { color: var(--text-muted); flex: 0 0 auto; }
.judge-fci-group-title { align-items: baseline; display: flex; gap: 0.5rem; }
.judge-fci-group ul { columns: 2 14rem; margin: 0.5rem 0 0; padding-left: 1rem; }
.judge-fci-group small { color: var(--text-muted); }
.users-card { overflow: hidden; }
.users-table-wrap { overflow-x: auto; }
.users-table { border-collapse: collapse; min-width: 520px; width: 100%; }
.users-table th, .users-table td { border-bottom: 1px solid var(--border-color); padding: 0.6875rem 0.5rem; text-align: left; }
.users-table th { color: var(--text-muted); font: 700 .7rem var(--font-display); text-transform: uppercase; }
.users-table td { color: var(--text-secondary); font-size: .84rem; }
.users-table td strong { color: var(--text-primary); display: block; }
.users-table .user-name-cell { align-items: center; display: flex; gap: 0.625rem; }
/* The name is a button, and a button centres its text: a name on two lines stood
   in the middle on a phone (Dimas, 2026-10-30, SHOW-94). */
.users-table .user-card-trigger { text-align: left; }
.users-card-head { align-items: center; display: flex; flex-wrap: wrap; gap: .5rem 1rem; justify-content: space-between; margin-bottom: 1rem; }
.users-card-head .settings-card-title { margin-bottom: 0; }
.users-card-head .users-search { flex: 1 1 8rem; margin-left: auto; max-width: 16rem; min-width: 0; width: auto; }
.users-search-empty { color: var(--text-muted); margin: 0 0 1rem; }
.users-table .user-list-avatar { background: var(--bg-base); border: 1px solid var(--border-color); border-radius: 50%; flex-shrink: 0; height: 36px; object-fit: cover; width: 36px; }
.users-table .user-list-avatar-placeholder { align-items: center; color: var(--text-secondary); display: flex; font: 700 .9rem var(--font-display); justify-content: center; }
.users-table td.user-registered, .users-table td.user-last-seen { white-space: nowrap; }
.users-table th.user-lists-head, .users-table td.user-lists { white-space: nowrap; font-variant-numeric: tabular-nums; }
.users-table td.user-last-seen .user-last-seen-ago { color: var(--text-muted); }
.users-table td small { color: var(--accent-text); display: block; }
.user-role { border-radius: 20px; display: inline-block; font: 700 .7rem var(--font-display); padding: 0.1875rem 0.5rem; text-transform: uppercase; }
.user-role-admin { background: rgba(var(--accent-primary-rgb),.12); color: var(--accent-text); }
.user-role-user { background: rgba(var(--color-orders-rgb),.12); color: var(--color-orders); }
.user-actions, .form-actions { align-items: center; display: flex; gap: 0.4375rem; }
.user-actions form { margin: 0; }
/* A flex <td> leaves the table box model, so its border stops tracking the row
   and draws a stub beside the buttons. Keep action cells as real cells. */
.users-table td.user-actions { display: table-cell; vertical-align: middle; white-space: nowrap; }
.users-table td.user-actions > * { display: inline-block; margin: 0; vertical-align: middle; }
.users-table td.user-actions > * + * { margin-left: 7px; }
/* The rule above wins over .btn-premium's flex centring, which left the icon
   of an icon-only control pinned to the top left of its 34px box. Icon buttons
   stay inline in the cell and keep centring their glyph. */
.users-table td.user-actions > .action-icon-button { align-items: center; display: inline-flex; justify-content: center; }

/* Exposition catalogue --------------------------------------------------- */
/* Season sources: one card per calendar year. */
.season-source-grid { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 28px; }
.season-source { display: flex; flex-direction: column; gap: 0.75rem; margin: 0; }
.season-source:hover { transform: none; }
.season-source-active { box-shadow: var(--shadow-premium), inset 0 0 0 1px rgba(var(--accent-primary-rgb),.35); }
.season-source-head { align-items: baseline; display: flex; gap: 0.625rem; justify-content: space-between; }
.season-source-head strong { color: var(--text-primary); font: 700 1rem var(--font-display); }
.season-source-year { background: rgba(var(--accent-primary-rgb),.12); border-radius: 20px; color: var(--accent-text); font: 700 .68rem var(--font-display); padding: 0.1875rem 0.5625rem; }
.season-source-url { color: var(--text-muted); font-size: .76rem; overflow: hidden; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; }
.season-source-url:hover { color: var(--accent-text); }
.season-source-stats { border-top: 1px solid var(--border-color); display: flex; gap: 1.625rem; margin: 0; padding-top: 0.75rem; }
.season-source-stats dt { color: var(--text-muted); font: 700 .64rem var(--font-display); letter-spacing: .04em; text-transform: uppercase; }
.season-source-stats dd { color: var(--text-primary); font-size: .84rem; margin: 3px 0 0; }
.season-source-stats dd a { color: var(--accent-text); text-decoration: none; }
.season-source-stats dd a:hover { text-decoration: underline; }
.season-source-result { color: var(--text-secondary); font-size: .76rem; margin: -4px 0 0; }
.season-source-actions { align-items: center; display: flex; gap: 0.5rem; margin-top: auto; }
.season-source-actions form { margin: 0; }
.season-source-actions .btn-premium { font-size: .74rem; padding: 0.5625rem 1rem; white-space: nowrap; width: auto; }

/* The narrated import. Hidden until a run starts, then a headline the reader
   watches and a log they can scroll back through — capped in height so a
   thirty-line run does not push the rest of the season grid off the screen. */
.season-import-run { border-top: 1px solid var(--border-color); display: flex; flex-direction: column; gap: 0.5rem; margin-top: 12px; padding-top: 0.75rem; }
.season-import-status { font-size: .78rem; line-height: 1.45; }
.season-import-status-running { color: var(--text-secondary); }
.season-import-status-ok { color: var(--accent-text); }
.season-import-status-error { color: var(--color-my-dogs); }
.season-import-status a { color: var(--accent-text); margin-left: 4px; }
.season-import-log { display: flex; flex-direction: column; gap: 0.25rem; list-style: none; margin: 0; max-height: 220px; overflow-y: auto; padding: 0; }
.season-import-line { color: var(--text-secondary); display: flex; font-size: .74rem; gap: 0.5rem; line-height: 1.4; }
.season-import-stage { color: var(--text-muted); flex: 0 0 52px; font: 700 .62rem var(--font-display); letter-spacing: .04em; padding-top: 0.125rem; text-transform: uppercase; }
.season-import-error span:last-child { color: var(--color-my-dogs); }
.season-import-warning span:last-child { color: var(--color-important); }
.season-import-done span:last-child { color: var(--accent-text); }

/* Year picker: the year view of a date field, on its own. */
.year-picker { position: relative; }
/* The panel sits in the flow rather than floating over the form: its host modal
   clips to its rounded corners, so an absolutely positioned grid lost its last
   row. Opening it grows the dialog instead, and the body scrolls if that runs
   the modal past the viewport. */
.year-picker-panel { background: var(--bg-base); border: 1px solid var(--border-highlight); border-radius: var(--radius-md); margin-top: 6px; padding: 0.75rem; }
.year-picker-head { align-items: center; display: flex; justify-content: space-between; margin-bottom: 10px; }
.year-picker-range { color: var(--text-primary); font: 700 .84rem var(--font-display); }
.year-picker-nav { background: none; border: none; border-radius: var(--radius-sm); color: var(--text-secondary); cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 0.25rem 0.625rem; }
.year-picker-nav:hover { background: var(--bg-overlay); color: var(--text-primary); }
.year-picker-grid { display: grid; gap: 0.375rem; grid-template-columns: repeat(3, 1fr); }
.year-picker-year { background: var(--bg-base); border: 1px solid transparent; border-radius: var(--radius-sm); color: var(--text-primary); cursor: pointer; font: 600 .84rem var(--font-display); padding: 0.5625rem 0; transition: var(--transition-premium); }
.year-picker-year:hover { background: var(--bg-overlay); }
.year-picker-year-now { border-color: rgba(var(--accent-primary-rgb),.45); }
.year-picker-year-active { background: var(--accent-primary); border-color: var(--accent-primary); color: #fff; }

/* Season tabs: the imported shows below belong to whichever year is active. */
.season-tabs { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: 16px; overflow-x: auto; }
.season-tab { align-items: center; border-bottom: 2px solid transparent; color: var(--text-secondary); display: inline-flex; font: 600 .86rem var(--font-display); gap: 0.4375rem; padding: 0.5625rem 0.875rem; text-decoration: none; transition: var(--transition-premium); white-space: nowrap; }
.season-tab:hover { background: var(--bg-overlay); color: var(--text-primary); }
.season-tab small { background: var(--bg-overlay); border-radius: 20px; color: var(--text-muted); font: 700 .68rem var(--font-display); padding: 0.125rem 0.4375rem; }
.season-tab-active { border-bottom-color: var(--accent-primary); color: var(--accent-text); }
.season-tab-active small { background: rgba(var(--accent-primary-rgb),.14); color: var(--accent-text); }

/* Imported shows: a card per show, its expositions listed inside. */
.expo-show-grid {
    display: grid;
    gap: 0.875rem;
}

.expo-show {
    margin: 0;
    padding: 0;
    container-type: inline-size;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    /* A #show-<id> link from the watch mail lands on the card, not under the
       fixed header and the card's own sticky head. */
    scroll-margin-top: calc(var(--header-height) + 1rem);
}

.expo-show:hover {
    transform: none;
}

/* The show name stays put while its expositions scroll, but it parks under the
   page header instead of at the viewport top -- and keeps --z-content, so a
   card can never paint over the header the way it did before. */
.expo-show-head {
    align-items: baseline;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-color);
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.75rem;
    justify-content: space-between;
    padding: 0.3125rem 0.9375rem 0.625rem 0.9375rem;
    position: sticky;
    top: var(--header-height);
    z-index: var(--z-content);
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
    box-sizing: content-box;
    /* The site's own `header` rule fixes every <header> at --header-height.
       This one is a card head that grows with its content: a check verdict on
       its own line pushed the place line out of a 66 px box and over the
       evidence strip below (DIM-631). */
    height: auto;
}


.expo-show-name {
    color: var(--text-primary);
    font: 700 .98rem var(--font-display);
    text-decoration: none;
}

.expo-show-name:hover {
    color: var(--accent-text);
}

.expo-show-name:focus-visible {
    border-radius: 3px;
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
}

/* The square-with-an-arrow beside the name: the exposition on cpc.pt. Sized to
   the check button next to it so the two read as one pair of controls. */
.expo-show-source {
    align-items: center;
    color: var(--text-muted);
    display: inline-flex;
    flex: 0 0 auto;
    justify-content: center;
    height: 26px;
    width: 26px;
    border-radius: 7px;
    text-decoration: none;
}

.expo-show-source .action-icon {
    height: 15px;
    width: 15px;
}

.expo-show-source:hover {
    background: var(--tint-subtle);
    color: var(--accent-text);
}

.expo-show-source:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.expo-show-name-orphan {
    color: var(--text-muted);
    font-style: italic;
    font-weight: 600;
}

/* The show's venue, once, on its own line at the foot of the head. The pin is
   decoration, hidden from screen readers, so it carries no spacing of its own. */
.expo-show-place {
    color: var(--text-muted);
    flex: 1 1 100%;
    font-size: .74rem;
}

.expo-show-place-pin {
    display: inline-block;
    height: 13px;
    margin-right: 4px;
    vertical-align: -2px;
    width: 13px;
}

.expo-show-meta {
    align-items: center;
    color: var(--text-muted);
    display: flex;
    flex-wrap: wrap;
    font-size: .76rem;
    gap: 0.5rem;
}

/* Catalogued and scheduled are two different imports. These say, at a glance,
   which shows still have no ring schedule behind them. */
.expo-schedule-pill { align-items: baseline; border: 1px solid transparent; border-radius: 999px; display: inline-flex; font: 700 .66rem var(--font-display); gap: 0.375rem; letter-spacing: .03em; padding: 0.1875rem 0.5625rem; white-space: nowrap; }
.expo-schedule-pill small { font-weight: 600; opacity: .75; }
.expo-schedule-complete { background: rgba(var(--color-friends-rgb), .12); border-color: rgba(var(--color-friends-rgb), .35); color: var(--color-friends); }
.expo-schedule-partial { background: rgba(var(--color-important-rgb), .12); border-color: rgba(var(--color-important-rgb), .35); color: var(--text-primary); } /* (Dimas, 2026-10-31, SHOW-127) */
.expo-schedule-source_found { background: rgba(var(--accent-primary-rgb), .08); border-color: rgba(var(--accent-primary-rgb), .3); color: var(--accent-text); }
.expo-schedule-missing { background: rgba(var(--color-my-dogs-rgb), .1); border-color: rgba(var(--color-my-dogs-rgb), .3); color: var(--color-my-dogs); }
.expo-schedule-stale { background: rgba(var(--accent-primary-rgb), .12); border-color: rgba(var(--accent-primary-rgb), .4); color: var(--accent-text); }
.schedule-legend { display: flex; flex-wrap: wrap; gap: 0.375rem; }

/* The same pills are the quick filter, so they have to look pressable. While a
   filter is on, the states left out fade back instead of disappearing — the
   counts are still the point of the row. */
.expo-schedule-filter { appearance: none; cursor: pointer; transition: var(--transition-premium); }
.expo-schedule-filter:hover { filter: brightness(1.25); }
.expo-schedule-filter[aria-pressed="true"] { border-color: currentColor; box-shadow: 0 0 0 2px rgba(var(--accent-primary-rgb), .28); }
.schedule-legend[data-filter-active] .expo-schedule-filter[aria-pressed="false"] { opacity: .4; }

/* One import per show day, run straight from the row. */
.expo-days { display: grid; gap: 0.375rem; grid-column: 1 / -1; margin-top: 4px; }
.expo-day { align-items: center; background: rgba(var(--bg-overlay-rgb), .35); border: 1px solid var(--border-color); border-left: 3px solid var(--border-highlight); border-radius: 8px; display: flex; flex-wrap: wrap; gap: 0.625rem; padding: 0.4375rem 0.625rem; }
.expo-day-missing { border-left-color: rgba(var(--color-my-dogs-rgb), .5); }
.expo-day-imported { border-left-color: rgba(var(--color-friends-rgb), .5); }
.expo-day-stale { border-left-color: var(--accent-primary); }
.expo-day-date { color: var(--text-primary); font: 700 .74rem var(--font-display); min-width: 74px; }
.expo-day-state { color: var(--text-secondary); flex: 1 1 auto; font-size: .72rem; min-width: 0; }
.expo-day-state small { color: var(--text-muted); }
.expo-day-missing .expo-day-state { color: var(--color-my-dogs); }
.expo-day-imported .expo-day-state { color: var(--color-friends); }
.expo-day-stale .expo-day-state { color: var(--accent-text); }
.expo-day-blocked { color: var(--text-muted); font-size: .7rem; font-style: italic; }
.expo-day-source-link { align-items: center; display: inline-flex; gap: 0.25rem; text-decoration: none; }
.expo-day-source-link:hover { color: var(--accent-text); }
.expo-day-source-link .action-icon { height: 12px; width: 12px; }
.expo-day .expo-day-import { align-items: center; display: inline-flex; flex: 0 0 auto; gap: 0.375rem; width: auto; min-height: 0; padding: 0.3125rem 0.625rem; border-radius: 7px; font: 700 .68rem var(--font-display); }
.expo-day .expo-day-import .action-icon { height: 14px; width: 14px; }
.expo-day .expo-day-import:disabled { cursor: progress; opacity: .6; }
.expo-day .expo-day-url { align-items: center; display: inline-flex; flex: 0 0 auto; width: auto; min-height: 0; padding: 0.3125rem 0.4375rem; border-radius: 7px; }
.expo-day .expo-day-url .action-icon { height: 14px; width: 14px; }
.expo-day .expo-day-url:disabled { cursor: progress; opacity: .6; }
.expo-day-message { flex: 1 1 100%; font-size: .7rem; color: var(--text-secondary); margin: 2px 0 0; }
.expo-day-message-error { color: var(--color-my-dogs); }

/* The run's own account of itself, under the day it belongs to. Capped and
   scrollable: a day that follows three Horários pages writes a dozen lines, and
   the list of days must stay readable while one of them is running. */
.expo-day-log { flex: 1 1 100%; display: flex; flex-direction: column; gap: 0.1875rem; list-style: none; margin: 6px 0 0; max-height: 180px; overflow-y: auto; padding: 0; }
.expo-day-log-line { color: var(--text-secondary); display: flex; font-size: .7rem; gap: 0.5rem; line-height: 1.4; }
.expo-day-log-stage { color: var(--text-muted); flex: 0 0 46px; font: 700 .58rem var(--font-display); letter-spacing: .04em; padding-top: 0.0625rem; text-transform: uppercase; }
.expo-day-log-failed span:last-child { color: var(--color-my-dogs); }
.expo-day-log-error span:last-child { color: var(--color-my-dogs); }
.expo-day-log-done span:last-child { color: var(--accent-text); }
/* What the importer found, under the day it was importing: the missing pieces,
   the page checks behind the verdict, and root's technical detail. */
.expo-day-diagnostics { flex: 1 1 100%; margin: 4px 0 0; }
.expo-day-diagnostics > * + * { margin-top: 4px; }
.expo-show-head .expo-show-check { align-items: center; display: inline-flex; flex: 0 0 auto; gap: 0.375rem; width: auto; min-height: 0; padding: 0.3125rem 0.5625rem; border-radius: 7px; font: 700 .68rem var(--font-display); letter-spacing: .04em; }
.expo-show-head .expo-show-check .action-icon { height: 15px; width: 15px; }

/* Everything that walks the whole list lives behind one trigger, so the
   section bar keeps one button no matter how many bulk runs there are. */
.bulk-actions { position: relative; }
.bulk-actions-trigger { align-items: center; display: inline-flex; gap: 0.375rem; justify-content: center; width: auto; }
.bulk-actions-menu { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.4); display: flex; flex-direction: column; max-width: min(320px, 84vw); min-width: 240px; overflow: hidden; position: absolute; right: 0; top: calc(100% + 6px); z-index: var(--z-popover); }
.bulk-actions-menu[hidden] { display: none; }
/* The season importer's menu hangs off its own trigger, which already sits at
   the right of a wide bar. The lists page's trigger sits at the left, and a menu
   anchored to a narrow trigger has nowhere to go: right:0 pushes it off the left
   of the screen, left:0 off the right. So it is anchored to the action bar
   instead, which spans the content — the panel lines up with the right edge of
   the page whatever the button under it is called or how wide it is. */
/* An open list has one control and it sits at the right, where a thumb holding
   the phone already is — the list itself is read down the left. The menu hangs
   off the bar rather than off the button, because the button is narrow: right:0
   against it would push the panel off the left of the screen. Anchored to the
   bar, which spans the content, both the button and the panel line up with the
   right edge of the page. */
.page-action-bar-end { justify-content: flex-end; }
.page-action-bar { position: relative; }
.page-action-bar .bulk-actions { position: static; }
.page-action-bar .bulk-actions-menu { left: auto; right: 0; }
.bulk-actions-trigger .action-icon { height: 15px; width: 15px; }
.bulk-actions-menu .bulk-menu-item { display: grid; gap: 0.125rem; }
.bulk-actions-menu .bulk-menu-item small { color: var(--text-muted); font-size: .72rem; font-weight: 500; }
/* Opened upwards when it would run under the bottom bar (placeBulkMenu, SHOW-165). */
.bulk-actions-menu.is-up { bottom: calc(100% + 6px); top: auto; }
.bulk-actions-menu .bulk-menu-item + .bulk-menu-item { border-top: 1px solid rgba(var(--border-color-rgb),.7); }

/* A left rail repeats the state on the card itself, so the list can be read by
   shape instead of by reading every pill. */
.expo-show-complete { border-left: 3px solid rgba(var(--color-friends-rgb), .45); }
.expo-show-partial { border-left: 3px solid rgba(var(--color-important-rgb), .55); }
.expo-show-missing { border-left: 3px solid rgba(var(--color-my-dogs-rgb), .55); }

/* nowrap so the button always stays on the show name's line; a long name
   wraps its own text instead of pushing the button down. */
.expo-show-title { align-items: center; display: flex; flex-wrap: wrap; gap: 0.625rem; min-width: 0; }
/* The check's verdict takes the whole next line rather than squeezing the name:
   its evidence is several lines long once opened. */
.expo-show-title > .expo-check-result { flex: 1 1 100%; }
.expo-catalogue-url:not([hidden]) { align-items: center; display: inline-flex; flex: 1 1 100%; gap: 0.5rem; }
.expo-catalogue-url input { flex: 1 1 auto; max-width: 28rem; min-width: 0; }
.expo-show-title .expo-show-name { min-width: 0; }
/* Icon-only by default; the label appears when the card is wide enough.
   Scoped under .expo-show-head to outrank the later .btn-premium base rule,
   which is full width by default. */
.expo-show-head .expo-show-import { align-items: center; display: inline-flex; flex: 0 0 auto; gap: 0.375rem; width: auto; min-height: 0; padding: 0.3125rem 0.5625rem; border-radius: 7px; font: 700 .68rem var(--font-display); letter-spacing: .04em; }
.expo-show-head .expo-show-import .action-icon { height: 15px; width: 15px; }
.expo-show-head .expo-show-import-label { display: none; }
@container (min-width: 440px) { .expo-show-head .expo-show-import-label { display: inline; } }

.expo-list { display: grid; list-style: none; margin: 0; padding: 0; }
.expo-item { align-items: center; display: grid; gap: 0.375rem 1rem; grid-template-columns: 74px minmax(0, 1fr) auto auto; padding: 0.75rem 1.25rem; }
.expo-item + .expo-item { border-top: 1px solid rgba(var(--border-color-rgb),.7); }
.expo-date { color: var(--accent-text); font: 700 .76rem var(--font-display); }
.expo-body { display: grid; gap: 0.125rem; min-width: 0; }
.expo-name { color: var(--text-primary); font-size: .86rem; }
.expo-place { color: var(--text-muted); font-size: .74rem; }
.expo-tags { display: flex; flex-wrap: wrap; gap: 0.3125rem; justify-content: flex-end; }
.expo-tag { background: rgba(var(--accent-primary-rgb),.1); border-radius: 20px; color: var(--accent-text); font: 700 .64rem var(--font-display); padding: 0.1875rem 0.5625rem; white-space: nowrap; }
.expo-tag-open { background: rgba(var(--color-friends-rgb),.12); color: var(--color-friends); }
.expo-tag-muted { background: rgba(var(--text-muted-rgb),.14); color: var(--text-muted); }
.expo-tag-alert { background: rgba(var(--color-my-dogs-rgb),.14); color: var(--color-my-dogs); }
.expo-actions { margin: 0; }
.expo-item-removed .expo-name, .expo-item-removed .expo-place, .expo-item-removed .expo-date { opacity: .55; text-decoration: line-through; }

.import-warning-list { color: var(--text-secondary); font-size: .82rem; margin: 0; padding-left: 1.125rem; }
.import-warning-list li + li { margin-top: 6px; }

/* Single-show editor: two-column form, full-width fields where it helps. */
.show-edit-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.show-edit-form .field-wide { grid-column: 1 / -1; }
.expo-edit-card { padding-top: 1rem; }
.expo-edit-card:hover { transform: none; }
.expo-edit-card-removed { opacity: .72; }
.expo-edit-head { align-items: center; border-bottom: 1px solid var(--border-color); display: flex; flex-wrap: wrap; gap: 0.375rem 0.75rem; margin-bottom: 18px; padding-bottom: 0.875rem; }
.expo-edit-head strong { color: var(--text-primary); font: 700 .92rem var(--font-display); margin-right: auto; }
.expo-edit-tools { align-items: center; border-top: 1px solid var(--border-color); display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 18px; padding-top: 0.875rem; }
.expo-edit-tools form { align-items: center; display: flex; gap: 0.5rem; margin: 0; }
.expo-edit-tools .btn-premium { font-size: .72rem; padding: 0.5rem 0.75rem; width: auto; }
.expo-move-form { margin-left: auto !important; }
.expo-move-form select { font-size: .78rem; max-width: 210px; padding: 0.4375rem 0.625rem; }
.expo-lock-note { align-items: center; background: rgba(var(--accent-primary-rgb),.07); border-radius: var(--radius-sm); color: var(--text-secondary); display: flex; flex-wrap: wrap; gap: 0.625rem; font-size: .8rem; justify-content: space-between; margin-top: 18px; padding: 0.75rem 0.875rem; }
/* Root's "use despite the mismatch" on a show card: a filled button, not one more
   pill — beside the status pills it read as a tag (Dimas, 2026-10-28) */
.expo-catalogue-accept { display: inline-flex; margin: 0; }
.expo-catalogue-explain { display: inline-flex; align-items: center; justify-content: center; padding: 0.125rem; border: 0; background: none; color: var(--text-secondary); cursor: pointer; }
.expo-catalogue-explain:hover, .expo-catalogue-explain:focus-visible { color: var(--accent-text); }
.expo-catalogue-explain .action-icon { width: 1.25rem; height: 1.25rem; }
.catalogue-explain-status:empty { display: none; }
.catalogue-explain-part h3 { margin: 1rem 0 0.375rem; font-size: 0.95rem; }
.catalogue-explain-part:first-of-type h3 { margin-top: 0; }
.catalogue-explain-part ul { margin: 0; padding-left: 1.25rem; }
.catalogue-explain-part li { margin: 0.25rem 0; line-height: 1.4; }
.catalogue-explain-wrong h3 { color: var(--color-important); }
#catalogue-explain-modal .catalogue-explain-structured[hidden] { display: none; }
#catalogue-explain-modal .catalogue-explain-banner { margin: 0 0 1rem; padding: 0.625rem 0.875rem; border: 1px solid var(--border-color); border-left-width: 4px; border-radius: 8px; line-height: 1.4; }
#catalogue-explain-modal .catalogue-explain-banner.is-verified { border-color: rgba(var(--color-friends-rgb), .5); background: rgba(var(--color-friends-rgb), .1); }
#catalogue-explain-modal .catalogue-explain-banner.is-accepted { border-color: rgba(var(--color-important-rgb), .5); background: rgba(var(--color-important-rgb), .1); }
#catalogue-explain-modal .catalogue-explain-banner.is-failed { border-color: rgba(var(--color-my-dogs-rgb), .5); background: rgba(var(--color-my-dogs-rgb), .1); }
#catalogue-explain-modal .modal-container { max-width: min(760px, calc(100vw - 24px)); }
#catalogue-explain-modal .catalogue-explain-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; margin-bottom: 1rem; }
#catalogue-explain-modal .catalogue-explain-stat { min-width: 0; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color); border-radius: 8px; background: var(--bg-card); }
#catalogue-explain-modal .catalogue-explain-stat-label { display: block; font-size: 0.75rem; color: var(--text-secondary); }
#catalogue-explain-modal .catalogue-explain-stat-value { display: block; font-size: 1.125rem; font-weight: 700; font-variant-numeric: tabular-nums; overflow-wrap: break-word; }
@media (max-width: 560px) {
    #catalogue-explain-modal .catalogue-explain-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    #catalogue-explain-modal .catalogue-explain-stat:last-child { grid-column: 1 / -1; }
}
#catalogue-explain-modal .catalogue-explain-block { margin-bottom: 1rem; }
#catalogue-explain-modal .catalogue-explain-block h3, #catalogue-explain-modal .catalogue-explain-notes h3 { margin: 0 0 0.375rem; font-size: 0.95rem; }
#catalogue-explain-modal .catalogue-explain-scroll { overflow-x: auto; max-width: 100%; border: 1px solid var(--border-color); border-radius: 8px; scrollbar-color: var(--border-color) transparent; scrollbar-width: thin; }
#catalogue-explain-modal .catalogue-explain-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
#catalogue-explain-modal .catalogue-explain-table th, #catalogue-explain-modal .catalogue-explain-table td { padding: 0.375rem 0.625rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border-color); }
#catalogue-explain-modal .catalogue-explain-table tbody tr:last-child td { border-bottom: 0; }
#catalogue-explain-modal .catalogue-explain-table th { font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); background: var(--bg-card); white-space: nowrap; }
#catalogue-explain-modal .catalogue-explain-table .is-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
#catalogue-explain-modal .catalogue-explain-table .is-wrap { min-width: 14rem; overflow-wrap: anywhere; }
#catalogue-explain-modal .catalogue-explain-table .is-nowrap { white-space: nowrap; }
#catalogue-explain-modal .catalogue-explain-table .is-diff { color: var(--color-important); font-weight: 600; }
#catalogue-explain-modal .catalogue-explain-table .is-zero { color: var(--text-secondary); }
#catalogue-explain-modal .catalogue-explain-table tr.is-total td { font-weight: 600; }
#catalogue-explain-modal .catalogue-explain-meter { margin-bottom: 1rem; }
#catalogue-explain-modal .catalogue-explain-meter-bar { height: 6px; border-radius: 3px; background: var(--bg-overlay); overflow: hidden; }
#catalogue-explain-modal .catalogue-explain-meter-fill { height: 100%; background: var(--color-important); }
#catalogue-explain-modal .catalogue-explain-meter-fill.is-over { background: var(--color-my-dogs); }
#catalogue-explain-modal .catalogue-explain-meter-caption { margin: 0.375rem 0 0; font-size: 0.8125rem; color: var(--text-secondary); }
#catalogue-explain-modal .catalogue-explain-notes p { margin: 0.25rem 0; font-size: 0.8125rem; line-height: 1.4; color: var(--text-secondary); }
.expo-catalogue-accept-button.btn-premium { width: auto; min-height: 0; padding: 0.3125rem 0.75rem; border-radius: 7px; font-size: .68rem; letter-spacing: .04em; white-space: nowrap; }

/* A show's catalogues on its settings page (settings/catalogue_panel.php) */
.catalogue-card:hover { transform: none; }
.catalogue-intro, .catalogue-empty { color: var(--text-secondary); font-size: .85rem; margin: 0 0 0.875rem; }
.catalogue-item { border-top: 1px solid var(--border-color); padding: 0.875rem 0; }
.catalogue-item-failed .catalogue-item-head strong { color: var(--accent-text); }
.catalogue-item-head { align-items: baseline; display: flex; flex-wrap: wrap; gap: 0.375rem 0.75rem; }
.catalogue-item-head strong { color: var(--text-primary); font: 700 .88rem var(--font-display); }
.catalogue-source { color: var(--text-muted); font-size: .78rem; overflow-wrap: anywhere; }
.catalogue-exhibitions { color: var(--text-secondary); font-size: .82rem; margin: 0.5rem 0 0.625rem; padding-left: 1.1rem; }
.catalogue-item form .btn-premium { font-size: .72rem; padding: 0.5rem 0.75rem; width: auto; }
.catalogue-form { border-top: 1px solid var(--border-color); margin-top: 0.25rem; padding-top: 0.875rem; }
.expo-lock-note form { margin: 0; }
.expo-lock-note .btn-premium { font-size: .72rem; padding: 0.4375rem 0.6875rem; width: auto; }
.expo-danger-card { box-shadow: var(--shadow-premium), inset 0 0 0 1px rgba(var(--color-my-dogs-rgb),.25); }
.expo-danger-card:hover { transform: none; }
.expo-danger-card .settings-intro { margin-bottom: 14px; }
.expo-danger-card .btn-premium { width: auto; }

@media (max-width: 640px) {
    .show-edit-form { grid-template-columns: minmax(0, 1fr); }
    /* Keep Move and the delete button sharing one line instead of stacking. */
    .expo-move-form { flex: 1 1 160px; margin-left: 0 !important; }
    .expo-move-form select { flex: 1; max-width: none; min-width: 0; }
}

@media (max-width: 720px) {
    .expo-item { grid-template-columns: minmax(0, 1fr) auto; }
    .expo-date { grid-column: 1; }
    .expo-body { grid-column: 1 / -1; }
    .expo-tags { grid-column: 1; justify-content: flex-start; }
    .expo-actions { grid-column: 2; grid-row: 1; justify-self: end; }
}
.user-actions .btn-premium, .form-actions .btn-premium { font-size: .7rem; padding: 0.4375rem 0.5625rem; text-decoration: none; width: auto; }
.btn-danger { background: rgba(var(--color-my-dogs-rgb),.12); color: var(--color-my-dogs); }
.btn-danger:hover { background: rgba(var(--color-my-dogs-rgb),.22); }
.action-icon-button { flex: 0 0 34px; height: 34px; padding: 0 !important; width: 34px !important; }
.action-icon { display: block; height: 17px; width: 17px; }
.auth-page { align-items: center; display: flex; justify-content: center; min-height: 100vh; padding: 1.5rem; }
.auth-card { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: var(--radius-lg); box-shadow: var(--shadow-premium); max-width: 420px; padding: 2rem; width: 100%; }
.auth-card h1 { margin-top: 24px; }
.auth-card h1.auth-title-center { text-align: center; } /* Sign in (SHOW-114) */
.auth-card > p { color: var(--text-secondary); margin: 4px 0 22px; }
.auth-card .auth-switch { border-top: 1px solid var(--border-color); font-size: .8rem; margin: 22px 0 0; padding-top: 1.125rem; text-align: center; }
.auth-switch a { align-items: center; display: inline-flex; font-weight: 700; gap: 0.25rem; }
.database-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.database-actions p { color: var(--text-muted); font-size: .75rem; margin-top: 5px; max-width: 220px; }
/* clip, not hidden: hidden makes the card a scroll container and the head would stick to it instead of the page. */
.test-dashboard { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: var(--radius-md); box-shadow: var(--shadow-premium); overflow: clip; }
.test-dashboard-summary { position: relative; align-items: center; background: linear-gradient(110deg, var(--bg-card), var(--bg-surface)); border-bottom: 1px solid var(--border-color); display: flex; gap: 1rem; justify-content: space-between; padding: 1.125rem 1.25rem; }
/* Same strip as .nav-progress, in the green of the OK tally: finished tests over the run's tests. */
.test-dashboard-summary .test-run-bar { background: var(--color-friends); border-radius: 0 2px 2px 0; bottom: -1px; height: 2px; left: 0; pointer-events: none; position: absolute; transition: width .3s ease-out; width: 0; }
.test-run-bar::after { background: var(--color-friends); border-radius: 999px; box-shadow: 0 0 6px 1px rgba(var(--color-friends-rgb), .6), 0 0 12px 3px rgba(var(--color-friends-rgb), .45); content: ""; height: 2px; position: absolute; right: 0; top: 50%; transform: translate(50%, -50%); width: 12px; }
.test-run-bar[data-empty]::after { display: none; }
@media (prefers-reduced-motion: reduce) { .test-dashboard-summary .test-run-bar, .test-dashboard-summary .test-run-bar[data-done] { transition: none; } }
.test-dashboard-summary span { color: var(--text-muted); font-size: .8rem; }
.test-dashboard-summary .test-progress { color: var(--text-primary); display: block; font: 700 1rem var(--font-display); font-variant-numeric: tabular-nums; }
/* The text span and the finished-run check inherit the line's size and colour, not the muted .8rem of plain spans. */
.test-dashboard-summary .test-progress > span { color: inherit; font: inherit; }
.test-dashboard-summary .test-progress > .test-done-mark { align-items: center; color: var(--color-friends); display: inline-flex; margin-left: .4rem; vertical-align: middle; }
.test-done-mark[hidden] { display: none; }
.test-done-mark svg { height: 1em; width: 1em; }
.test-done-mark .test-done-icon { display: none; }
.test-done-mark[data-test-verdict="passed"] .test-done-icon-passed,
.test-done-mark[data-test-verdict="warning"] .test-done-icon-warning,
.test-done-mark[data-test-verdict="failed"] .test-done-icon-failed { display: block; }
.test-dashboard-summary .test-progress > .test-done-mark[data-test-verdict="warning"] { color: var(--color-important); }
.test-dashboard-summary .test-progress > .test-done-mark[data-test-verdict="failed"] { color: var(--color-my-dogs); }
/* A finished run: the line first reaches full width, then fades away. */
.test-dashboard-summary .test-run-bar[data-done] { opacity: 0; transition: width .3s ease-out, opacity .4s ease-out .35s; }
.test-dashboard-actions { display: flex; gap: 0.5rem; }
.test-dashboard-actions .btn-premium { font-size: .76rem; padding: 0.5rem 0.6875rem; }
/* One run button (SHOW-95): a play icon to run, a red Stop with a square while a run goes on. */
.test-run-button { gap: 0.375rem; }
.test-dashboard-summary .test-run-button span { color: inherit; font-size: inherit; }
.test-run-icon { fill: currentColor; flex: 0 0 auto; height: 0.875rem; width: 0.875rem; }
.test-run-button .test-run-icon-stop, .test-run-button[data-running] .test-run-icon-play { display: none; }
.test-run-button[data-running] .test-run-icon-stop { display: block; }
.test-run-button[data-running] { background-color: var(--color-my-dogs); box-shadow: 0 4px 15px rgba(var(--color-my-dogs-rgb), 0.25); }
.test-run-button[data-running]:hover { background-color: #DC2626; box-shadow: 0 6px 20px rgba(var(--color-my-dogs-rgb), 0.35); }
.test-run-button:disabled { cursor: default; opacity: .55; }
/* Title, run buttons and tallies park under the site header while the table scrolls. */
.test-dashboard-head { background: var(--bg-surface); border-bottom: 1px solid var(--border-color); position: sticky; top: var(--header-height); z-index: var(--z-content); }
.test-command { align-items: flex-end; color: var(--text-secondary); display: flex; flex-wrap: wrap; font-size: .8rem; gap: 0.5rem; padding: 0.875rem 1.25rem 0.75rem; }
.test-command span { color: var(--text-muted); display: block; font-size: .7rem; margin-bottom: 4px; text-transform: uppercase; }
/* The label keeps its own line above the command; the tallies sit off to the right. */
.test-command > span:first-child { flex-basis: 100%; margin-bottom: 0; }
.test-command code { background: var(--bg-base); border: 1px solid var(--border-color); border-radius: 5px; color: var(--text-primary); display: inline-block; padding: 0.3125rem 0.5rem; }

/* Tally and filter in one control: the number says how many, pressing it shows which. */
.test-command .test-filters { display: inline-flex; gap: 0.375rem; margin-bottom: 0; margin-left: auto; }
.test-filter { background: var(--bg-base); border: 1px solid var(--border-color); border-radius: 5px; color: var(--text-muted); cursor: pointer; font: 700 .68rem var(--font-display); letter-spacing: .04em; padding: 0.3125rem 0.5625rem; }
.test-filter span { color: var(--text-primary); display: inline; font-size: .78rem; margin: 0 0 0 5px; text-transform: none; }
.test-filter:hover { border-color: var(--text-muted); }
/* Each tally wears its state's colour at rest; pressing it fills the chip. */
.test-filter-passed { border-color: rgba(var(--color-friends-rgb),.45); color: var(--color-friends); }
.test-filter-warning { border-color: rgba(var(--color-important-rgb),.45); color: var(--color-important); }
.test-filter-skipped { border-color: rgba(var(--color-orders-rgb),.45); color: var(--color-orders); }
.test-filter-failed { border-color: rgba(var(--color-my-dogs-rgb),.45); color: var(--color-my-dogs); }
.test-filter-passed:hover { border-color: var(--color-friends); }
.test-filter-warning:hover { border-color: var(--color-important); }
.test-filter-skipped:hover { border-color: var(--color-orders); }
.test-filter-failed:hover { border-color: var(--color-my-dogs); }
/* Grey until there is something to count; a pressed filter keeps its colour. */
.test-filter[data-test-empty] { border-color: var(--border-color); color: var(--text-muted); }
.test-filter[data-test-empty]:hover { border-color: var(--text-muted); }
.test-filter span { color: inherit; }
.test-filter-passed[aria-pressed="true"] { background: rgba(var(--color-friends-rgb),.16); border-color: var(--color-friends); color: var(--color-friends); }
.test-filter-warning[aria-pressed="true"] { background: rgba(var(--color-important-rgb),.16); border-color: var(--color-important); color: var(--text-primary); } /* (Dimas, 2026-10-31, SHOW-127) */
.test-filter-skipped[aria-pressed="true"] { background: rgba(var(--color-orders-rgb),.16); border-color: var(--color-orders); color: var(--color-orders); }
.test-filter-failed[aria-pressed="true"] { background: rgba(var(--color-my-dogs-rgb),.16); border-color: var(--color-my-dogs); color: var(--color-my-dogs); }
.test-filter[aria-pressed="true"] span { color: inherit; }
.test-table-wrap { overflow-x: auto; padding: 0.875rem 1.25rem 1.25rem; }
.test-table { border-collapse: collapse; min-width: 620px; width: 100%; }
.test-table th { border-bottom: 1px solid var(--border-color); color: var(--text-muted); font: 700 .7rem var(--font-display); letter-spacing: .05em; padding: 0.5625rem 0.5rem; text-align: left; text-transform: uppercase; }
.test-table td { border-bottom: 1px solid rgba(var(--border-color-rgb),.7); color: var(--text-secondary); font-size: .82rem; padding: 0.8125rem 0.5rem; vertical-align: top; }
.test-table tr:last-child td { border-bottom: 0; }
/* Runtime, the last column: figures flush right in equal-width digits (Dimas, 2026-11-02). */
.test-table th:last-child, .test-table td:last-child { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.test-table strong { color: var(--text-primary); display: block; font-family: var(--font-display); }
.test-table small { color: var(--text-muted); display: block; font: .73rem monospace; margin-top: 2px; }
.test-table input { accent-color: var(--accent-primary); cursor: pointer; }
.test-status { font-family: var(--font-display); font-weight: 700; }
.test-status.passed { color: var(--color-friends); }
.test-status.failed { color: var(--color-my-dogs); }
.test-status.skipped { color: var(--color-orders); }
.test-status.warning { color: var(--color-important); }
/* The row currently executing, while the run walks the table one test at a time. */
.test-status.running { color: var(--color-important); }
/* A CSS-only spinner in front of the status text while a test runs or analyses in the background. */
.test-status.running::before { animation: test-spin .8s linear infinite; border: 2px solid currentColor; border-radius: 50%; border-right-color: transparent; content: ""; display: inline-block; height: .8em; margin-right: .45rem; vertical-align: -.1em; width: .8em; }
@keyframes test-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .test-status.running::before { animation: none; } }
.test-copy { align-items: center; background: transparent; border: 1px solid var(--border-color); border-radius: var(--radius-sm, 6px); color: var(--text-muted); cursor: pointer; display: inline-flex; height: 1.75rem; justify-content: center; margin-left: 0.5rem; padding: 0; vertical-align: middle; width: 1.75rem; }
.test-copy svg { fill: none; height: 0.95rem; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2; width: 0.95rem; }
.test-copy:hover, .test-copy:focus-visible { border-color: var(--color-my-dogs); color: var(--text-primary); }
.test-copy.copied { border-color: var(--color-friends); color: var(--color-friends); }
.visually-hidden-copy { left: -9999px; opacity: 0; position: fixed; top: 0; }
.test-table details { color: var(--text-primary); cursor: pointer; }
.test-table summary { font-size: .78rem; }
.test-table pre { color: var(--text-secondary); font: .72rem/1.4 monospace; margin-top: 8px; max-width: 300px; white-space: pre-wrap; }
@media (max-width: 560px) { .test-dashboard-summary { align-items: stretch; flex-direction: column; } .test-dashboard-actions .btn-premium { flex: 1; } }
@media (max-width: 620px) { .settings-menu { grid-template-columns: 1fr; } }
@media (max-width: 700px) { .judges-directory { grid-template-columns: 1fr; } }
@media (max-width: 760px) { .judge-edit-layout { grid-template-columns: 1fr; } }
@media (hover: none), (pointer: coarse) { .judge-card-controls { opacity: 1; pointer-events: auto; transform: none; } }
@media (max-width: 520px) { .settings-section-bar, .directory-tools { align-items: stretch; flex-direction: column; } .judge-card-heading { align-items: flex-start; flex-wrap: wrap; } .judge-card-controls { margin-left: 54px; } }
/* The tools row stacks its own children on a narrow screen, and a stretched
   column makes every button full width. The buttons here are short labels next
   to a count, so the row stays a row that wraps, and they keep their own size. */
@media (max-width: 520px) {
    /* flex-end so that if the row does wrap on a very narrow screen, what
       wrapped stays with the buttons on the right rather than starting a new
       left-aligned line of its own. */
    .directory-tools { align-items: center; flex-direction: row; flex-wrap: wrap; justify-content: flex-end; }
    .directory-tools .btn-premium { flex: 0 0 auto; width: auto; }
    /* The tools row is full width once the section bar stacks, so the count
       holds the left edge and the buttons are pushed to the right together. */
    .directory-tools .directory-count { margin-right: auto; }
}
@media (max-width: 520px) { .header-tools { gap: 0; } .account-avatar { height: 30px; margin: 0 8px; width: 30px; } .account-avatar svg { height: 17px; width: 17px; } }
@media (max-width: 620px) { .benefit-banner { align-items: stretch; flex-direction: column; } .benefit-actions .btn-premium { flex: 1; } }

/* Upcoming Table Layout (Distinctive, minimalist approach) */
.matches-list {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    margin-bottom: 24px;
    box-shadow: var(--shadow-premium);
}

.match-item {
    display: grid;
    grid-template-columns: 70px 1fr 100px;
    align-items: center;
    padding: 0.3125rem 0.3125rem 0.3125rem 1.25rem;
    border-bottom: 1px solid var(--border-color);
    position: relative;
    transition: var(--transition-premium);
}

.match-item:last-child {
    border-bottom: none;
}

.match-item:hover {
    background-color: var(--tint-subtle);
}

.match-priority-indicator {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background-color: var(--prio-color, var(--border-color));
}

.match-time-ring {
    display: flex;
    flex-direction: column;
}

.match-time {
    font-family: var(--font-display);
    /* The ring tables' size: there .schedule-table td (0.86rem) outranks the
       cell's own 0.95rem, so the tracker read a size bigger (Dimas, 2026-11-01, SHOW-127). */
    font-size: 0.86rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--text-primary);
}

/* The tracker's two switches. Both read as ticks, so the off state is a real
   button rather than an absence — the pair has to look like two independent
   things, not like one choice with two options. */
.tracker-filters { display: flex; gap: 0.5rem; justify-content: flex-end; margin-bottom: 14px; }
.tracker-filter {
    align-items: center;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-muted);
    display: inline-flex;
    font: 700 .78rem var(--font-display);
    gap: 0.375rem;
    padding: 0.375rem 0.875rem;
    text-decoration: none;
    transition: var(--transition-premium);
}
.tracker-filter.active {
    background: rgba(var(--accent-primary-rgb), .14);
    border-color: var(--accent-primary);
    color: var(--text-primary);
}
.tracker-filter:not(.active) .favorite-star { color: var(--border-color); }

/* Said beside the Rings heading only while a ring is actually working. */
.live-tag {
    background: var(--color-friends);
    border-radius: 4px;
    color: #06210F;
    display: inline-block;
    font: 800 .62rem var(--font-display);
    letter-spacing: .06em;
    margin-left: 8px;
    padding: 0.1875rem 0.4375rem;
    text-transform: uppercase;
    vertical-align: middle;
}

.breed-lists-check {
    align-items: center;
    cursor: pointer;
    display: flex;
    font-family: var(--font-display);
    font-weight: 600;
    gap: 0.625rem;
}
.breed-lists-check input { height: 18px; width: 18px; accent-color: var(--accent-primary); }
.breed-lists-lists { display: flex; flex-direction: column; gap: 0.75rem; }
.breed-lists-lists .group-form { margin: 0; }

/* The star that marks a favourite. Hollow until it is one, and always in the
   accent colour, so one glance down a list finds them. */
.favorite-star {
    background: none;
    border: 0;
    color: var(--border-color);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.25rem 0 0;
    transition: var(--transition-premium);
}
.favorite-star.is-favorite { color: var(--accent-text); }
@media (hover: hover) {
    .favorite-star:hover { color: var(--accent-text); }
}

/* A breed that sits on one of the viewer's lists carries that list's colour
   after its name, so a ring reads for one's own dogs without being read. */
/* Beside a time that is not the one the timetable printed. */
.time-shifted {
    background: var(--color-my-dogs);
    border-radius: 50%;
    display: inline-block;
    height: 6px;
    margin-left: 0;
    vertical-align: middle;
    width: 6px;
}

.breed-list-dot {
    border-radius: 50%;
    display: inline-block;
    height: 7px;
    margin-left: 2px;
    vertical-align: middle;
    width: 7px;
}

.time-ahead {
    display: block;
    font-family: var(--font-display);
    font-size: 0.65rem; /* a step down for "+1h 31m" with its space (Dimas, 2026-11-01, SHOW-127) */
    font-weight: 700;
    line-height: 1.3;
    color: var(--text-muted);
}

/* The ring is a jump to that ring's card, so it is a button — styled as the
   label it has always been, and reachable from a keyboard because of it. */
.match-ring {
    background: none;
    border: 0;
    cursor: pointer;
    padding: 0;
    text-align: left;
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--accent-text);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding-top: 0.25rem;
}

.match-details {
    display: flex;
    flex-direction: column;
    padding-right: 0.75rem;
}

.match-breed {
    font-family: var(--font-display);
    font-size: 0.86rem; /* as the ring tables, see .match-time (SHOW-127) */
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.2;
    padding-bottom: 0.125rem;
}

.match-meta {
    align-items: center;
    display: flex;
    gap: 0.25rem;
    justify-content: flex-end;
    text-align: right;
}

.match-dogs {
    font-size: 0.86rem;
    color: var(--text-secondary);
}

.match-order {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* The tracker: folded by its heading, passed breeds behind an eye, any row
   shrunk to one quiet line by a swipe (Dimas, 2026-10-26). No size is new:
   every font here is one the tracker already used. */
.tracker-header { margin-bottom: 8px; }
.tracker-fold {
    align-items: center;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
    display: inline-flex;
    font: inherit;
    gap: 0.4rem;
    letter-spacing: inherit;
    padding: 0;
    text-transform: inherit;
}
.tracker-chevron { height: 1em; transition: transform .15s; width: 1em; }
.tracker-header[data-folded] .tracker-chevron { transform: rotate(-90deg); }
.tracker-eye {
    align-items: center;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    line-height: 0;
    order: 1;
    padding: 0.375rem 0.625rem;
}
.tracker-eye[aria-pressed="true"] {
    background: rgba(var(--accent-primary-rgb), .14);
    border-color: var(--accent-primary);
    color: var(--text-primary);
}
.tracker-eye .action-icon { height: 1.4rem; width: 1.4rem; }
.tracker-header[data-folded] .tracker-eye { display: none; }
[data-tracker][data-folded] { display: none; }

.match-item { touch-action: pan-y; }
.match-shrink { background: none; border: 0; color: var(--text-muted); cursor: pointer; line-height: 0; padding: 0.25rem; }
.match-shrink .action-icon { height: 1em; transform: rotate(180deg); width: 1em; }
.match-item.is-shrunk .match-shrink .action-icon { transform: none; }
.match-item.is-passed .match-shrink { display: none; }
.match-title { align-items: flex-start; display: flex; gap: 0.25rem; }
.match-marks { flex: none; white-space: nowrap; }
/* The marks sit on one line box with the breed's first line, so the icon is
   centred on the text instead of riding the body's taller line (SHOW-127). */
.match-title .match-marks { align-items: center; display: flex; font-size: 0.86rem; height: calc(0.86rem * 1.2); line-height: 1.2; }
.match-text { display: flex; flex-direction: column; min-width: 0; }
.match-title .match-breed { padding-bottom: 0; }
.match-details { padding-bottom: 0.25rem; padding-top: 0.25rem; }
.match-note { color: var(--text-muted); font-size: 0.75rem; line-height: 1.2; }
.match-left { color: var(--text-secondary); font-size: 0.75rem; }
.match-empty { color: var(--text-muted); font-size: 0.8rem; padding: 0.5rem 1.25rem; }

.match-item.is-passed { display: none; opacity: .6; }
.match-item.is-passed.is-latest-passed,
[data-tracker].show-passed .match-item.is-passed { display: grid; }

.match-item.is-shrunk {
    grid-template-columns: auto 1fr auto;
    opacity: .5;
    padding-bottom: 0.125rem;
    padding-top: 0.125rem;
}
.match-item.is-shrunk > * { min-width: 0; }
.match-item.is-shrunk .match-time-ring { align-items: baseline; flex-direction: row; gap: 0.5rem; }
.match-item.is-shrunk .match-time,
.match-item.is-shrunk .match-ring,
.match-item.is-shrunk .match-breed,
.match-item.is-shrunk .match-dogs,
.match-item.is-shrunk .match-note,
.match-item.is-shrunk .match-left { font-size: 0.65rem; line-height: 1.2; padding: 0; }
.match-item.is-shrunk .match-details {
    align-items: center;
    flex-direction: row;
    gap: 0.375rem;
    overflow: hidden;
    padding-bottom: 0;
    padding-top: 0;
    white-space: nowrap;
}
.match-item.is-shrunk .match-title { align-items: center; }
.match-item.is-shrunk .match-text { align-items: center; flex-direction: row; gap: 0.375rem; min-width: 0; }
.match-item.is-shrunk .match-note { overflow: hidden; text-overflow: ellipsis; }
.match-item.is-shrunk .match-breed { overflow: hidden; text-overflow: ellipsis; }

/* LIVE RING TRACKER (Signature Element Grid) */
.rings-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    margin-bottom: 32px;
}

/* One column up to 800px (Dimas, 2026-10-31): narrower, two rings side by
   side squeeze the breed names into two and three lines and the judge to a letter. */
@media (min-width: 801px) {
    .rings-grid {
        grid-template-columns: 1fr 1fr;
    }
}

.ring-node {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    box-shadow: var(--shadow-premium);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    position: relative;
    overflow: hidden;
    transition: var(--transition-premium);
}

.ring-node:hover {
    border-color: var(--border-highlight);
    box-shadow: 0 15px 35px -10px rgba(0,0,0,0.8);
}

.ring-node.active-ring {
    border-color: rgba(var(--accent-primary-rgb), 0.4);
    box-shadow: 0 0 20px rgba(var(--accent-primary-rgb), 0.1);
}

.ring-node-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.25rem;
    margin-bottom: 16px;
}

.ring-node-heading {
    min-width: 0;
}

.ring-node-title {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--text-primary);
}

.ring-node-judge {
    font-size: 0.75rem;
    color: var(--text-muted);
    line-height: 1.25;
    margin-top: 2px;
    /*max-width: 55%;*/
    text-align: right;
}

.ring-node-judge span,
.ring-node-judge strong {
    display: block;
}

.ring-node-judge strong {
    color: var(--text-secondary);
    font-weight: 600;
}

.ring-node-delay {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 700;
    margin-top: 6px;
    padding: 0.1875rem 0.5rem;
    border-radius: 6px;
}

/* Red, not amber: a late ring is the one thing on the card that changes what
   you do next, and amber reads as a note. The palette's red is the same one
   errors use. */
.ring-node-delay.delayed {
    background-color: rgba(var(--color-my-dogs-rgb), 0.12);
    color: var(--color-my-dogs);
    border: 1px solid rgba(var(--color-my-dogs-rgb), 0.3);
}

.ring-node-delay.early {
    background-color: rgba(var(--color-friends-rgb), 0.1);
    color: var(--color-friends);
    border: 1px solid rgba(var(--color-friends-rgb), 0.2);
}

.ring-th-delay { float: right; font-size: 0.64rem; font-weight: 700; letter-spacing: 0; text-transform: none; }
.ring-th-delay.delayed { color: var(--color-my-dogs); }
.ring-th-delay.early { color: var(--color-friends); }

.ring-node-body {
    background-color: rgba(var(--bg-base-rgb), 0.4);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 0.875rem;
    margin-bottom: 16px;
}

.ring-sequence-row {
    align-items: baseline;
    display: grid;
    gap: 0.625rem;
    grid-template-columns: 46px minmax(0, 1fr);
    line-height: 1.25;
    min-width: 0;
}

.ring-sequence-row + .ring-sequence-row {
    margin-top: 10px;
}

.ring-sequence-row time {
    font-variant-numeric: tabular-nums;
}

.ring-sequence-muted {
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 400;
}

.ring-sequence-muted span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ring-sequence-current {
    color: var(--text-primary);
    font-family: var(--font-display);
    font-size: 1.17rem;
    font-weight: 800;
}

.ring-sequence-current strong {
    min-width: 0;
    overflow-wrap: anywhere;
}

.ring-sequence-current small {
    color: var(--text-secondary);
    font-size: 0.68em;
    font-weight: 600;
    white-space: nowrap;
}

/* Button & UI elements */
.btn-premium {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.75rem;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
    transition: var(--transition-premium);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
    /* An <a> styled as a button is still a link to the browser: it arrives
       underlined and in the visited colour unless both are said here. */
    text-decoration: none;
    color: var(--text-primary);
}

.btn-premium-primary {
    background-color: var(--accent-primary);
    color: white;
    box-shadow: 0 4px 15px rgba(var(--accent-primary-rgb), 0.2);
}

.btn-premium-primary:hover {
    background-color: #E06B00;
    box-shadow: 0 6px 20px rgba(var(--accent-primary-rgb), 0.35);
}

/* A disabled button looks it and takes no clicks, e.g. Copy link for 2 s
   after a copy (SHOW-144). */
.btn-premium:disabled,
.btn-premium:disabled:hover {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
    box-shadow: none;
}

.btn-premium-secondary {
    background-color: var(--bg-overlay);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
}

.btn-premium-secondary:hover {
    background-color: var(--tint-subtle-strong);
}

/* Lists styling */
.list-item-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.375rem 0;
    border-bottom: 1px solid var(--border-color);
}
/* A list's breeds sit close (Dimas, 2026-10-31, SHOW-147): the card's own
   .75rem above and below plus .875rem per row made one breed 88px tall. */
#list-items.card-premium { padding-bottom: 0.25rem; padding-top: 0.25rem; }

.list-item-row:last-child {
    border-bottom: none;
}

/* Forms styling */
.group-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* ONE style for every text field, select and textarea (Dimas, 2026-10-31,
   SHOW-127). :where() keeps the specificity of the first selector at zero, so a
   component rule that differs on purpose (a compact search field, a number cell)
   sets only what differs: size, padding, width, never colour or border. */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="image"]):not([type="reset"]), select, textarea),
.input-field {
    background-color: var(--bg-input);
    border: 1px solid var(--border-input);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 0.95rem;
    padding: 0.625rem 0.75rem;
    transition: var(--transition-premium);
}
:where(input, textarea)::placeholder { color: var(--text-muted); }

.input-field { width: 100%; }

:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="image"]):not([type="reset"]), select, textarea):focus,
.input-field:focus {
    outline: none;
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 3px rgba(var(--accent-primary-rgb), 0.15);
}

/* The colour swatch field, one rule for every dialog that has one. */
input[type="color"] { background: var(--bg-input); border: 1px solid var(--border-input); border-radius: var(--radius-sm); height: 42px; padding: 0.1875rem; width: 60px; }

.input-field[type="date"]::-webkit-calendar-picker-indicator,
.input-field[type="time"]::-webkit-calendar-picker-indicator {
    filter: invert(1) brightness(2);
    cursor: pointer;
}

.label-field {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary);
    margin-bottom: 6px;
    display: block;
}

/* A row of buttons that open the page's modals, standing where the form it
   replaced used to be. */
.page-action-bar { display: flex; flex-wrap: wrap; gap: 0.625rem; margin-top: 20px; }
/* .btn-premium is a full-width block by default, which is right inside a form
   and wrong in a row of actions: one button there stretched across the page and
   read as a banner rather than as something to press. Here each button is as
   wide as its own words. */
.page-action-bar .btn-premium { flex: 0 0 auto; width: auto; }

/* Not even on a phone: a button as wide as the screen reads as a banner, and
   these are ordinary actions. They wrap onto the next line instead. */
.page-action-bar .btn-premium { max-width: 100%; }

.modal-lede { color: var(--text-secondary); font-size: .84rem; margin-bottom: 16px; }

/* Autocomplete suggestion popups */
.autocomplete-container {
    position: relative;
}

.suggestions-box {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-highlight);
    border-radius: var(--radius-sm);
    max-height: 220px;
    overflow-y: auto;
    z-index: var(--z-popover);
    box-shadow: 0 10px 25px rgba(0,0,0,0.8);
}

.suggestion-node {
    padding: 0.75rem 1rem;
    cursor: pointer;
    border-bottom: 1px solid var(--border-color);
    transition: var(--transition-premium);
}

.suggestion-node:hover {
    background-color: var(--bg-overlay);
}

/* A breed already in the list: shown, not pickable. */
.suggestion-node.is-in-list {
    opacity: .45;
    cursor: default;
}

.suggestion-node.is-in-list:hover {
    background-color: transparent;
}

.modal-body .suggestions-box { position: static; margin-top: 6px; box-shadow: none; max-height: 190px; }

/* Bottom Bar PWA Navigation */

/* Five tabs, and the middle one is not a tab.

   The dashboard is where every other page leads back to, and it used to be the
   first of five identical cells — the far corner of a phone, the last place a
   thumb reaches. It is now a circle in the centre of the bar, standing above
   it, with the other four pushed in towards it. The bar is shorter than it was
   by exactly enough for the circle to stand proud without growing the strip of
   screen the navigation costs. */
.bar-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(var(--bg-surface-rgb), 0.96);
    backdrop-filter: blur(16px);
    border-top: 1px solid var(--border-color);
    padding: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    /* Above all page content, and level with the sticky header. */
    z-index: var(--z-chrome);
    box-shadow: 0 -10px 30px rgba(0,0,0,0.5);
    /* viewport-fit=cover: keep the tabs clear of the iOS home indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

.bar-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.7rem;
    font-family: var(--font-display);
    font-weight: 600;
    gap: 0.1875rem;
    transition: var(--transition-premium);
    padding: 0.375rem 0.375rem 0.4375rem;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    /* The four ordinary tabs share the bar evenly. min-width:0 lets a long word
       ellipsise inside its own tab instead of pushing the neighbours off. */
    flex: 1 1 0;
    min-width: 0;
    /* Room in the middle for the circle, which is taken out of the flow. */
    max-width: 5.5rem;
}

.bar-tab-word {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bar-icon { display: block; position: relative; }

/* The Settings tab shows the account: its photograph in a ring that takes the
   tab's colour, and the unread feedback count on the corner
   (Dimas, 2026-10-31, SHOW-127). */
.bar-avatar-img {
    border-radius: 50%;
    box-shadow: 0 0 0 1px currentColor;
    display: block;
    height: 22px;
    object-fit: cover;
    width: 22px;
}

.bar-unread {
    align-items: center;
    background: var(--color-my-dogs);
    border: 2px solid var(--bg-surface);
    border-radius: 999px;
    color: #fff;
    display: flex;
    font: 700 .62rem/1 var(--font-display);
    height: 18px;
    justify-content: center;
    min-width: 18px;
    padding: 0 0.3em;
    position: absolute;
    right: -8px;
    top: -4px;
}

.bar-icon-glyph {
    display: block;
    height: 22px;
    width: 22px;
}

.bar-tab:hover {
    color: var(--text-primary);
    background-color: var(--tint-subtle);
}

.bar-tab.active {
    color: var(--accent-text);
    background-color: rgba(var(--accent-primary-rgb), 0.08);
    border-color: rgba(var(--accent-primary-rgb), 0.2);
    box-shadow: inset 0 0 10px rgba(var(--accent-primary-rgb), 0.05);
}

/* The hub: a circle lifted clear of the bar, wider than a tab and taller than
   the bar it sits in. It stands well proud rather than merely peeping over the
   edge — half of it is above the border, which is what makes it read as one
   button rather than as a fifth tab with a round background.

   margin-top is negative by the amount it rises, so the bar's own height is
   unchanged and the page below it needs no extra clearance. */
.bar-tab-hub {
    align-items: center;
    background: linear-gradient(160deg, var(--accent-primary) 0%, rgba(var(--accent-primary-rgb), .78) 100%);
    border: 3px solid var(--bg-surface);
    border-radius: 999px;
    box-shadow: 0 6px 18px rgba(var(--accent-primary-rgb), .45);
    color: #fff;
    flex: 0 0 auto;
    gap: 0;
    height: 68px;
    justify-content: center;
    margin: -32px 0.625rem 0;
    padding: 0;
    width: 68px;
}

.bar-tab-hub:hover,
.bar-tab-hub.active {
    background-color: transparent;
    border-color: var(--bg-surface);
    box-shadow: 0 8px 22px rgba(var(--accent-primary-rgb), .6);
    color: #fff;
}

/* The circle says which page it is by being the circle. Its word would have to
   sit outside it, on the bar, level with nothing. */
.bar-tab-hub .bar-tab-word { display: none; }

.bar-tab-hub .bar-icon-glyph {
    height: 30px;
    stroke-width: 1.8;
    width: 30px;
}

/* --- Navigation feedback ---------------------------------------------------- */

/* The instant answer to a tap on a link: an orange strip along the header's
   bottom edge that creeps toward the right and does not arrive while the old
   page is waiting, a pressed look on the link itself, and a line under the
   header if the page is still not here after 8 seconds. initNavigationFeedback()
   in app.js sets html.is-navigating and .nav-pending.

   The strip never blinks: on pagehide app.js stores how far it got, and
   nav-arrive.js (in <head>, so before first paint) puts html.nav-arriving and
   --nav-from on the new page. The strip is in the header markup, so it exists
   at first paint and nav-finish carries it from there to 100% and fades it. */
.nav-progress {
    background: var(--nav-progress);
    border-radius: 0 2px 2px 0;
    bottom: -1px;
    height: 2px;
    left: 0;
    opacity: 0;
    pointer-events: none;
    position: absolute;
    width: 0;
}

.nav-progress::after {
    background: var(--nav-progress);
    border-radius: 999px;
    box-shadow: 0 0 6px 1px var(--accent-glow), 0 0 12px 3px rgba(var(--accent-primary-rgb), .45);
    content: "";
    height: 2px;
    position: absolute;
    right: 0;
    top: 50%;
    transform: translate(50%, -50%);
    width: 12px;
}

/* Declared before is-navigating, so a new tap wins over a finishing strip. */
html.nav-arriving .nav-progress {
    animation: nav-finish .55s ease-out forwards;
}

/* One curve over the whole run, with a soft start. The timing function
   applies to each keyframe segment, so the old 0/5/30/100% stops shot to 30%
   in 0.6 s, braked, and lunged again (Dimas, 2026-10-27: smoother start). */
html.is-navigating .nav-progress {
    animation: nav-progress 12s cubic-bezier(.3, .55, .25, 1) forwards,
               nav-progress-in .2s ease-out forwards;
}

@keyframes nav-progress {
    from { width: 0; }
    to { width: 92%; }
}

@keyframes nav-progress-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* The page has arrived: continue from where the last page left the strip. */
@keyframes nav-finish {
    0% { width: var(--nav-from, 30%); opacity: 1; }
    45% { width: 100%; opacity: 1; }
    100% { width: 100%; opacity: 0; }
}


.bar-tab .bar-icon { transition: transform .12s ease-out; }

.bar-tab.nav-pending { color: var(--nav-progress); }
.bar-tab.nav-pending .bar-icon { transform: scale(.86); }

.bar-tab-hub.nav-pending {
    /* The hub is orange already, so an orange ring would not show. */
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .35), 0 8px 22px rgba(var(--accent-primary-rgb), .6);
    color: #fff;
    transform: scale(.92);
}

a.nav-pending:not(.bar-tab) { opacity: .65; }

.nav-slow {
    background: rgba(var(--bg-surface-rgb), .95);
    border: 1px solid rgba(var(--accent-primary-rgb), .5);
    border-radius: 999px;
    color: var(--text-primary);
    font: 600 .78rem var(--font-display);
    left: 50%;
    max-width: calc(100vw - 2rem);
    overflow: hidden;
    padding: .375rem .75rem;
    position: absolute;
    text-overflow: ellipsis;
    top: 100%;
    transform: translate(-50%, .375rem);
    white-space: nowrap;
}

.nav-slow[hidden] { display: none; }

/* Reduced motion keeps the strip: a 2px progress line is the answer the
   reader is waiting for, not decoration, and a static or fading-only strip
   was exactly the blink it exists to remove (Dimas, 2026-10-27). */
@media (prefers-reduced-motion: reduce) {
    .bar-tab .bar-icon { transition: none; }
}

/* --- Viewport slip (iOS 26 WebKit) ---------------------------------------- */

/* Where the screen really is, when WebKit has lost it.

   On iOS 26, after a text field has had the keyboard and let it go, the layout
   viewport -- the box position:fixed and position:sticky are measured against --
   can stay shifted down inside the screen (WebKit bug 297779, Apple
   FB19889436). The header leaves the top of the screen and the bottom bar sits
   across the middle of the page; in a home-screen app nothing ever puts it
   back, which is why the bar is right in Safari and floats in the app (Dimas,
   2026-10-21). initViewportAnchor() in app.js measures the shift from the
   visual viewport and writes it into these two properties; wherever the browser
   behaves they stay 0px and nothing here moves.

   translate rather than transform, because it composes with the transform a
   rule already has (the saving pill's translateX, the pull indicator's
   translateY) instead of replacing it. The modal overlay is moved by its insets
   instead: a translate would make it the containing block of the map's fixed
   close button, which would then scroll away with the map. */
:root { --viewport-slip-top: 0px; --viewport-slip-bottom: 0px; }
header,
.toast-container,
.ptr-indicator,
.expo-show-head,
.show-title-filter,
.rings-sticky,
.rings-sticky ~ .schedule-ring-tables .schedule-ring-table > h2,
.rings-sticky ~ .schedule-own-view > .schedule-own-head,
.translation-letter h2 { translate: 0 var(--viewport-slip-top); }
.bar-nav,
.consent-bar,
.notify-saving,
.reorder-panel,
.offline-banner,
.bulk-fab-container { translate: 0 var(--viewport-slip-bottom); }

/* Toast Notifications */
/* Under the header, never over it: the header stays clickable while a toast
   shows (Dimas, 2026-10-29, SHOW-55). */
.toast-container {
    position: fixed;
    top: calc(var(--header-height) + 12px);
    left: 50%;
    transform: translateX(-50%);
    width: 90%;
    max-width: 400px;
    z-index: var(--z-notice);
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.toast {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1rem 1.25rem;
    box-shadow: 0 20px 40px rgba(0,0,0,0.8);
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    position: relative;
    animation: slide-down 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    transition: opacity 0.3s ease, transform 0.3s ease;
}

@keyframes slide-down {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.toast-error {
    border-left: 4px solid var(--color-my-dogs);
    border-color: rgba(var(--color-my-dogs-rgb), 0.3) rgba(var(--color-my-dogs-rgb), 0.3) rgba(var(--color-my-dogs-rgb), 0.3) var(--color-my-dogs);
}

.toast-success {
    border-left: 4px solid var(--color-friends);
    border-color: rgba(var(--color-friends-rgb), 0.3) rgba(var(--color-friends-rgb), 0.3) rgba(var(--color-friends-rgb), 0.3) var(--color-friends);
}

.toast-icon {
    font-size: 1.25rem;
    line-height: 1;
    margin-top: 2px;
}

.toast-content {
    flex: 1;
}

.toast-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.95rem;
    margin-bottom: 2px;
}

.toast-message {
    font-size: 0.85rem;
    color: var(--text-secondary);
    line-height: 1.4;
}

.toast-close {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.2rem;
    cursor: pointer;
    line-height: 1;
    transition: var(--transition-premium);
}

.toast-close:hover {
    color: var(--text-primary);
}

/* Modal System */
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    /* The dialog scrolls inside the overlay, and the scroll stops there: a
       gesture that runs past its end must not be handed to the page behind. */
    overflow: auto;
    overscroll-behavior: contain;
    padding: 0.75rem;
    background-color: rgba(var(--bg-base-rgb), 0.8);
    backdrop-filter: blur(12px);
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
/* Moved by its insets, not a translate: see the viewport slip block above. */
.modal-overlay { bottom: calc(-1 * var(--viewport-slip-bottom)); top: var(--viewport-slip-bottom); }

.modal-overlay.active {
    opacity: 1;
    pointer-events: auto;
}

.modal-container {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-highlight);
    border-radius: var(--radius-lg);
    width: 90%;
    max-width: min(520px, calc(100vw - 24px));
    /* A flex item refuses to shrink below its content's min-content width
       unless it is told to. The ring picker's <select> is as wide as its
       longest breed name, so on a phone the dialog grew past the screen and
       the page could be dragged sideways behind it. */
    min-width: 0;
    box-shadow: var(--shadow-premium), 0 30px 60px -15px rgba(0, 0, 0, 0.9);
    transform: scale(0.92) translateY(10px);
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
    overflow: hidden;
    /* A dialog that grows -- the year grid opening, a long form -- stops at the
       viewport and scrolls its body, instead of running off both edges where
       overflow: hidden puts it out of reach. */
    display: flex;
    flex-direction: column;
    max-height: 90vh;
}

.modal-overlay.active .modal-container {
    transform: scale(1) translateY(0);
}

.modal-header {
    padding: 1.125rem 1.5rem;
    border-bottom: 1px solid var(--border-color);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
}

.modal-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: -0.01em;
    color: var(--text-primary);
}

.breed-lists-title { line-height: 1; }
.breed-lists-title-name { cursor: pointer; }
.breed-lists-rename-toggle {
    background: none;
    border: 0;
    color: var(--text-secondary);
    cursor: pointer;
    display: inline-block;
    font-size: inherit;
    line-height: 0;
    margin-left: 0.375rem;
    padding: 0;
    vertical-align: -0.08em;
}
.breed-lists-rename-toggle:hover, .breed-lists-rename-toggle[aria-expanded="true"] { color: var(--accent-text); }
.breed-lists-rename-toggle .action-icon { height: 1em; width: 1em; }
.breed-lists-rename { margin-bottom: 1.25rem; }
.breed-lists-rename-save { margin-top: 0.75rem; }
.breed-lists-rename small { color: var(--text-muted); display: block; margin-top: 0.375rem; }

.modal-close {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.6rem;
    cursor: pointer;
    line-height: 1;
    transition: var(--transition-premium);
    padding: 0.25rem;
}

.modal-close:hover {
    color: var(--color-my-dogs);
}

.modal-body {
    padding: 1.5rem;
    overflow-y: auto;
    min-width: 0;
}

/* Same story one level down: a long option must not set the dialog's width. */
.modal-body select.input-field {
    max-width: 100%;
    text-overflow: ellipsis;
}

/* While a dialog is open the page behind it does not scroll — in either
   direction. Without this the document keeps its own scroll under a fixed
   overlay, which on a phone reads as the screen sliding about by itself. */
body.modal-open {
    overflow: hidden;
}
/* On an iPhone the body's overflow does not stop the page: it is pinned at the
   place it stood, and the script puts it back there on close (Dimas,
   2026-11-01, SHOW-127). */
html.scroll-locked { overflow: hidden; }
html.scroll-locked body { left: 0; position: fixed; right: 0; top: var(--scroll-lock-top, 0px); width: 100%; }

/* Shows Page Layout Styles */
.show-card-layout {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
}

/* The mark in front of a name: a green tick on a show that has run, a grey
   clock on one ahead without a timetable, nothing otherwise (DIM-787). */
.show-card-mark { align-items: center; display: inline-flex; flex: 0 0 auto; justify-content: center; transform: translateY(2px); }
.show-card-mark-icon { display: block; height: 17px; width: 17px; }
.show-card-mark-done { color: var(--color-friends); }
.show-card-mark-waiting { color: var(--text-secondary); }

/* The name's line: the mark, the name, a badge or the dates beside it, the
   settings cog. baseline alignment keeps them sitting with the type. */
.show-card-heading {
    align-items: baseline;
    display: flex;
    /* The dashboard pill puts an "on now" badge and the dates on this line
       beside the name, so it has to be able to take a second row on a phone. */
    flex-wrap: wrap;
    gap: 0 0.4375rem;
}


/* The show running today. The block only exists on those days, so it is the
   one thing on the page worth pointing at. The dashboard's show bar wears the
   same tint on the same days, so the two pages say "this one is on" alike. */
.show-section-now .section-header {
    color: var(--section-heading-now);
}

.show-section-now .show-card,
.active-show-bar.active-show-bar-now {
    border: 1px solid rgba(var(--accent-primary-rgb), .45);
    background: linear-gradient(135deg, rgba(var(--accent-primary-rgb), .1) 0%, var(--bg-surface) 60%);
}

#company_field {
    position: absolute;
    left: -5000px;
}
/* The past block is folded away above the rest of the page. Its own header
   scrolls off when it opens, so the toggle lives at the bottom, where it keeps
   its place on screen. */
.folded-section-toggle {
    align-items: center;
    background: none;
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    font: 700 .72rem var(--font-display);
    gap: 0.5rem;
    justify-content: center;
    letter-spacing: .06em;
    margin: 16px 0 4px;
    padding: 0.625rem 0.875rem;
    text-transform: uppercase;
    width: 100%;
}

.folded-section-toggle:hover {
    border-color: rgba(var(--accent-primary-rgb), .5);
    color: var(--accent-text);
}

/* Tags on a show card: what is missing, and what is still open. Wrapped so a
   card can carry both without either being pushed off the edge. */
.show-card-tags { display: flex; flex-wrap: wrap; gap: 0.375rem; }

/* The titles a show awards, coloured as cpc.pt colours them (DIM-789). */
.show-card-title {
    border: 1px solid;
    border-radius: 6px;
    display: inline-flex;
    font: 700 .75rem var(--font-display);
    letter-spacing: .02em;
    margin-top: 4px;
    padding: 0.1875rem 0.5rem;
    white-space: nowrap;
}
.show-card-title-cac { background: rgba(var(--color-friends-rgb), .12); border-color: rgba(var(--color-friends-rgb), .4); color: var(--color-friends); }
.show-card-title-cacib { background: rgba(var(--color-orders-rgb), .12); border-color: rgba(var(--color-orders-rgb), .45); color: var(--color-orders); }
.show-card-title-special { background: rgba(176, 96, 64, .14); border-color: rgba(176, 96, 64, .5); color: #c9805f; }

.show-card-tag {
    background: rgba(var(--color-my-dogs-rgb), .1);
    border: 1px solid rgba(var(--color-my-dogs-rgb), .3);
    border-radius: 999px;
    color: var(--color-my-dogs);
    display: inline-flex;
    font: 700 .66rem var(--font-display);
    letter-spacing: .03em;
    margin-top: 4px;
    padding: 0.1875rem 0.5625rem;
    white-space: nowrap;
}

/* Entries still open is the one piece of good news a card carries, so it is the
   one tag painted in the "go" colour rather than the warning one.

   After the base rule, not before it. Same specificity, so source order decides,
   and while this sat above .show-card-tag the base rule's `border` shorthand and
   `color` won and the tag came out in the warning colour. Invisible for as long
   as the tag itself was: it only ever appeared for three days after an import,
   so nobody was looking at a green that was not green. */
.show-card-tag-open {
    background: rgba(var(--color-friends-rgb), .12);
    border-color: rgba(var(--color-friends-rgb), .35);
    color: var(--color-friends);
}

/* Entries open with its closing day under it: two lines, so a rounded box
   rather than a pill (Dimas, 2026-11-02, SHOW-178). */
.show-card-tag-two { align-items: center; border-radius: .5rem; flex-direction: column; line-height: 1.25; padding: .25rem .5625rem; }
.show-card-tag-sub { font-weight: 600; letter-spacing: .02em; }

/* "No timetable" beside the name, on the name's line (SHOW-55). */
.show-card-tag-inline { margin: 9px 0 .375rem; padding: 0 .625rem; position: relative; top: -2px; vertical-align: middle; }

/* The state tag stands under the date or the countdown, on the right (DIM-799). */
.show-card-date .show-card-tag,
.active-show-countdown .show-card-tag { align-self: flex-end; margin-top: 0.375rem; }

/* The filter by title above the shows list (DIM-799). */
.show-title-filter { align-items: center; display: flex; flex-wrap: wrap; gap: 0.375rem; margin: 0 0 1rem; }
/* It stays under the header while the list scrolls (Dimas, 2026-10-20), on the
   page's own background so the cards pass under it, as the rings bar does. */
.show-title-filter { background: var(--bg-base); padding-bottom: 0.5rem; padding-top: 0.5rem; position: sticky; top: var(--header-height); z-index: var(--z-content); }
.show-title-filter-chip {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    color: var(--text-secondary);
    cursor: pointer;
    font: 700 .68rem var(--font-display);
    letter-spacing: .02em;
    min-height: 1.75rem;
    padding: 0.25rem 0.625rem; /* tighter: the row of titles took too much room (Dimas, 2026-10-20) */
    white-space: nowrap;
}
.show-title-filter-chip:hover { border-color: rgba(var(--accent-primary-rgb), .5); color: var(--text-primary); }
.show-title-filter-chip[aria-pressed="true"] { background: var(--accent-primary); border-color: var(--accent-primary); color: #fff; }
.show-title-filter-chip:focus-visible, .show-title-filter-clear:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.show-title-filter-clear { background: none; border: 0; color: var(--accent-text); cursor: pointer; font: 600 .78rem var(--font-body); padding: 0.375rem 0.25rem; }
.show-title-filter-clear[hidden], .show-card[hidden], .show-year-heading[hidden], .folded-section-toggle[hidden], .show-title-filter-empty[hidden] { display: none; }
.show-title-filter-empty { color: var(--text-muted); font-size: .85rem; margin: 0.5rem 0 1rem; }
/* On a phone the chips are one row that scrolls sideways: wrapped, six titles
   took three rows and pushed the first show half a screen down. */
@media (max-width: 600px) {
    .show-title-filter { flex-wrap: nowrap; margin-left: -1rem; margin-right: -1rem; overflow-x: auto; padding: 0.5rem 1rem; scrollbar-width: none; }
    .show-title-filter::-webkit-scrollbar { display: none; }
    .show-title-filter > * { flex-shrink: 0; }
}

.show-card-info {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

/* line-height 1: a show name is one line of display type sitting directly above
   its venue, and the font's own leading opened a gap that read as a paragraph
   break inside a single card. A name long enough to wrap still wraps. */
.show-card-name {
    color: var(--text-primary);
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    line-height: 1;
    text-decoration: none;
    transition: var(--transition-premium);
}

.show-card-place {
    align-items: baseline;
    color: var(--text-secondary);
    display: flex;
    font-size: 0.8rem;
    line-height: 1.2;
    margin: 4px 0 6px;
}

/* A show with nothing to open is paler than one you can, so the list says at
   a glance which names lead somewhere (Dimas, 2026-10-20, DIM-787). */
span.show-card-name { color: var(--text-unlinked); }
/* The steward's own show is the page they are on, not a show they cannot open. */
.assistant-sheet-head span.show-card-name { color: var(--text-primary); }

/* A show with no schedule is not a link — there is nothing behind it yet — so
   only the anchor answers to hover. */
a.show-card-name:hover {
    color: var(--accent-text);
}

.show-card-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.show-card-actions .btn-premium {
    width: auto;
    padding: 0.5rem 1rem;
    font-size: 0.8rem;
}

/* The days on one line, the year under them. "28 Feb - 1 Mar 2026" on one line
   either wrapped wherever it liked or pushed the name; and the days are what a
   reader is after, the year only what tells two Bejas apart. */
.show-card-date {
    display: flex;
    flex-direction: column;
    text-align: right;
}

.show-card-days {
    color: var(--accent-text);
    font: 700 1.2rem/1.1 var(--font-display); /* (Dimas, 2026-10-31, SHOW-127) */
    white-space: nowrap;
}

.show-card-year {
    color: var(--text-muted);
    font: 600 0.74rem/1.2 var(--font-display);
    letter-spacing: .04em;
    white-space: nowrap;
}

/* Schedule views: imported table and ring-by-ring day board */
.schedule-heading {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
    margin: 0 0 10px;
}

/* Root's link from a show to its card in Settings → Expositions. */
.show-settings-link {
    align-items: center;
    color: var(--accent-text);
    display: inline-flex;
    flex: 0 0 auto;
    font: 700 0.72rem/1 var(--font-display);
    gap: 0.375rem;
    letter-spacing: 0.04em;
    text-decoration: none;
}
.show-settings-link:hover { opacity: 0.8; }
.show-settings-link .action-icon { height: 16px; width: 16px; }
.show-settings-link-icon { margin-left: 0.25rem; vertical-align: middle; }


/* The title and the venue map button share one row, the button pressed to the
   right edge, on every width (DIM-778). */
.schedule-heading-main { flex: 1 1 auto; min-width: 0; }
.schedule-title-row { align-items: center; display: flex; gap: 0.75rem; justify-content: space-between; }
.schedule-title-row h1 { min-width: 0; overflow-wrap: anywhere; }
.show-map-button {
    align-items: center;
    background: var(--bg-surface);
    border: 1px solid var(--border-highlight);
    border-radius: var(--radius-md, 10px);
    color: var(--text-primary);
    cursor: pointer;
    display: inline-flex;
    flex: 0 0 auto;
    font: 700 0.78rem/1 var(--font-display);
    gap: 0.4rem;
    padding: 0.5rem 0.75rem;
}
.show-map-button:hover { border-color: var(--accent-primary); color: var(--accent-text); }
.show-map-button .action-icon { height: 18px; width: 18px; }

/* "About the show": a round "i" beside the title, the map button staying on the
   right edge; it never wraps below the title on a phone (SHOW-185). */
/* "About the show": the look of the active "All dogs" switch (SHOW-185). */
.show-info-button { align-items: center; background: rgba(var(--accent-primary-rgb), .14); border: 1px solid var(--accent-primary); border-radius: 8px; color: var(--text-primary); display: inline-flex; flex: 0 0 auto; font-family: var(--font-display); font-size: 0.875rem; font-weight: 700; margin-right: auto; min-height: 36px; padding: 0 0.75rem; text-decoration: none; transition: var(--transition-premium); white-space: nowrap; }
.show-info-button:hover { background: rgba(var(--accent-primary-rgb), .24); color: var(--text-primary); }

/* The map itself: the whole screen, the picture as large as it fits, one
   Close button. A map larger than the screen scrolls inside the frame. */
.show-map-modal { flex-direction: column; gap: 0.75rem; padding: 4rem 0.75rem 0.75rem; } /* the top keeps the × off the map */
.show-map-frame {
    align-items: center;
    display: flex;
    flex: 1 1 auto;
    justify-content: center;
    min-height: 0;
    overflow: auto;
    width: 100%;
}
.show-map-image {
    background: #fff;
    border-radius: var(--radius-md, 10px);
    display: block;
    height: auto;
    max-height: calc(100vh - 8.75rem);
    max-height: calc(100dvh - 8.75rem);
    max-width: 100%;
    object-fit: contain;
    width: auto;
}
.show-map-close { flex: 0 0 auto; min-width: 9rem; }
.modal-overlay .show-map-x {
    align-items: center;
    background-color: var(--accent-primary);
    border: none;
    border-radius: var(--radius-sm);
    box-shadow: 0 4px 15px rgba(var(--accent-primary-rgb), 0.35);
    color: white;
    display: inline-flex;
    font-size: 1.9rem;
    height: 2.75rem;
    justify-content: center;
    line-height: 1;
    padding: 0 0 0.15rem;
    position: fixed;
    right: 0.75rem;
    top: 0.75rem;
    width: 2.75rem;
    z-index: 2;
}
.modal-overlay .show-map-x:hover { color: white; filter: brightness(1.1); }
/* Root's settings link shares the subtitle's row, pressed to the right. */
.schedule-subtitle-row { align-items: baseline; display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; justify-content: space-between; }

.schedule-subtitle { color: var(--text-secondary); font-size: 0.84rem; margin-top: 6px; }
.schedule-subtitle a { color: inherit; text-decoration: underline dotted; text-underline-offset: 3px; }
.changes-day { margin-top: 1.25rem; scroll-margin-top: 1rem; }
.changes-day-title { font-size: 1rem; margin: 0 0 0.5rem; }
.changes-head { font-weight: 600; margin-top: 0.75rem; overflow-wrap: anywhere; }
.changes-head:first-child { margin-top: 0; }
.changes-list { margin: 0.25rem 0 0; overflow-wrap: anywhere; padding-left: 1.125rem; }

/* About a show (SHOW-185): section headings, one card per day, plain lists. */
.show-info-section { margin-top: 1.25rem; }
.show-info-section-title { font-size: 1.1rem; font-weight: 700; margin: 0 0 0.5rem; }
/* The info hub (SHOW-186): a card per section, three to a row, one on a phone. */
.show-info-intro { color: var(--text-secondary); line-height: 1.5; margin: 0.5rem 0 0; max-width: 46rem; }
.show-info-hub { display: grid; gap: 0.75rem; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 1rem; }
/* SHOW-187: the icon (40px) and the title share one row, the caption sits under it. */
.show-info-tile { align-content: start; align-items: center; color: inherit; column-gap: 0.75rem; display: grid; grid-template-columns: 40px minmax(0, 1fr); margin-bottom: 0; padding: 1rem; row-gap: 0.4rem; text-decoration: none; }
.show-info-tile:not(.is-disabled):hover { box-shadow: 0 0 0 1px var(--accent-primary), var(--shadow-premium); }
.show-info-tile.is-disabled { cursor: default; opacity: 0.45; }
/* The timetable card keeps its tags readable: only its own content fades (SHOW-186). */
.show-info-tile.is-disabled.has-tags { opacity: 1; }
.show-info-tile.is-disabled.has-tags :is(.show-info-tile-icon, .show-info-tile-title, .show-info-tile-caption) { opacity: 0.45; }
/* "No timetable" right under the title, about the icon's height together (SHOW-186). */
.show-info-tile-titles { align-items: flex-start; display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.show-info-tile-titles .show-info-tile-title { line-height: 1.2; }
.show-info-tile-titles .show-card-tag-inline { margin: 0; top: 0; }
.show-info-tile-tags { align-items: center; display: flex; flex-wrap: wrap; gap: 0.5rem; grid-column: 1 / -1; }
.show-info-tile-tags .show-card-tag-inline { margin: 0; top: 0; }
.show-info-tile-icon { align-items: center; color: var(--accent-text); display: inline-flex; height: 40px; justify-content: center; width: 40px; }
.show-info-tile-icon .action-icon { height: 40px; width: 40px; }
.show-info-tile-title { font-size: 1.05rem; font-weight: 700; overflow-wrap: anywhere; }
.show-info-tile-caption { color: var(--text-secondary); font-size: 0.88rem; grid-column: 1 / -1; overflow-wrap: anywhere; }
@media (max-width: 600px) { .show-info-hub { grid-template-columns: minmax(0, 1fr); } }
.show-info-card { margin-bottom: 0.75rem; }
/* Final rings: a tab per day, date over the exposition's name (SHOW-187). */
.show-info-tabs .import-tab { align-items: center; display: flex; flex-direction: column; gap: 0.1rem; text-align: center; text-decoration: none; }
/* Folder tabs: the orange of the open tab runs on round its day's panel, so the
   tab and the panel read as one piece (Dimas, 2026-11-02, SHOW-187). */
.import-tabs.show-info-tabs { background: none; border: 0; border-radius: 0; gap: 0.25rem; margin-bottom: 0; padding: 0; }
.show-info-tabs .import-tab { background: var(--bg-surface); border-radius: var(--radius-md) var(--radius-md) 0 0; }
.show-info-tabs .import-tab.active { background: var(--accent-primary); color: #fff; }
.show-info-tabs + .show-info-section { margin-top: 0; }
.show-info-tabs + .show-info-section > [role="tabpanel"] { border: 2px solid var(--accent-primary); padding: 1.25rem 1.5rem; }
/* Room inside the tabs and around the day heading (Dimas, 2026-11-02, SHOW-187). */
.import-tabs.show-info-tabs .import-tab { padding: 0.85rem 1rem; }
.show-info-tabs + .show-info-section > [role="tabpanel"] > .show-info-day-title { margin: 0.25rem 0 1rem; }
.show-info-tabs:has(.import-tab:first-child.active) + .show-info-section > [role="tabpanel"] { border-top-left-radius: 0; }
.show-info-tabs:has(.import-tab:last-child.active) + .show-info-section > [role="tabpanel"] { border-top-right-radius: 0; }
/* The day on a tab twice the tab's text size (Dimas, 2026-11-02, SHOW-187). */
.show-info-tab-date { font-size: 1.3rem; font-weight: 700; line-height: 1.15; }
.show-info-back { margin-top: 1rem; }
.show-info-back .btn-premium { align-items: center; display: inline-flex; gap: 0.4rem; }
.show-info-back .action-icon { height: 18px; width: 18px; }
.show-info-tab-title { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.03em; opacity: 0.85; overflow-wrap: anywhere; }
/* A section page: its card's 40px icon beside the H1 (SHOW-187). */
.show-info-title-row { align-items: center; display: flex; gap: 0.75rem; }
.show-info-title-row h1 { margin: 0; }
/* Club shows: one crest for every club for now, beside the show's lines (SHOW-187). */
.show-info-event { align-items: flex-start; display: flex; gap: 0.75rem; }
.show-info-event-body { flex: 1 1 auto; min-width: 0; }
.show-info-club-mark { align-items: center; background: rgba(var(--accent-primary-rgb),.12); border: 1px solid rgba(var(--accent-primary-rgb),.25); border-radius: 50%; color: var(--accent-text); display: flex; flex: 0 0 auto; height: 42px; justify-content: center; width: 42px; }
.show-info-club-mark .action-icon { height: 22px; width: 22px; }
/* Breed clubs (SHOW-180): an approved logo fits its mark on a white ground; the club pages and the root list. */
.club-logo { background: #fff; border-radius: inherit; display: block; height: 100%; object-fit: contain; width: 100%; }
.club-title-mark, .club-card-mark { flex: 0 0 auto; }
.club-title-mark .club-logo, .club-card-mark .club-logo { border-radius: var(--radius-sm, 6px); }
.club-directory { display: grid; gap: 0.75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.club-card { align-items: flex-start; color: inherit; display: flex; gap: 0.75rem; text-decoration: none; }
.club-card:hover .club-card-name { color: var(--accent-text); }
.club-card-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.club-card-name { font-weight: 600; overflow-wrap: anywhere; }
.club-card-abbr { color: var(--text-secondary); font-size: 0.8rem; font-weight: 700; letter-spacing: 0.04em; }
.club-card-breeds { color: var(--text-secondary); font-size: 0.85rem; overflow-wrap: anywhere; }
.club-breeds { columns: 2 14rem; margin: 0; padding-left: 1.25rem; }
.club-facts { display: grid; gap: 0.25rem 1rem; grid-template-columns: auto minmax(0, 1fr); margin: 0; }
.club-facts dt { color: var(--text-secondary); font-weight: 600; }
.club-facts dd { margin: 0; overflow-wrap: anywhere; }
.club-logo-preview { background: #fff; border: 1px solid var(--border-color); border-radius: var(--radius-sm, 6px); flex: 0 0 auto; height: 56px; object-fit: contain; width: 56px; }
.club-admin-directory .judge-monogram .action-icon { height: 22px; width: 22px; }
.club-admin-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0 1rem 1rem; }
.club-admin-actions form { margin: 0; }
.club-admin-actions .btn-premium { font-size: 0.75rem; padding: 0.5rem 0.8rem; width: auto; }
@media (max-width: 700px) { .club-directory { grid-template-columns: minmax(0, 1fr); } }
/* One card per day, two days side by side on a wide screen (Dimas, 2026-11-02, SHOW-187). */
@media (min-width: 900px) {
    .show-info-days { align-items: start; display: grid; gap: 0.75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .show-info-days > .show-info-card { margin-bottom: 0; }
}
.show-info-venue-name { align-items: center; color: inherit; display: flex; font-weight: 600; gap: 0.5rem; overflow-wrap: anywhere; text-decoration: none; }
.show-info-venue-name + .show-info-venue-name { margin-top: 0.5rem; }
a.show-info-venue-name:hover span { text-decoration: underline; }
/* The pin is red whatever the theme: it is the map's own marker colour (SHOW-187). */
.show-info-pin { color: #e53935; flex: 0 0 auto; height: 22px; width: 22px; }
/* SHOW-187: the venue map's iframe fills a box of fixed height. */
.show-info-map { border-radius: var(--radius-md, 10px); height: 360px; overflow: hidden; }
.show-info-map-frame { border: 0; display: block; height: 100%; width: 100%; }
@media (max-width: 600px) { .show-info-map { height: 280px; } }
.show-info-source { color: var(--text-secondary); font-size: 0.85rem; margin: 1rem 0 0; overflow-wrap: anywhere; }
.show-info-source a { color: inherit; text-decoration: underline; }
.show-info-venue-image { background: #fff; border-radius: var(--radius-md, 10px); display: block; height: auto; max-width: 100%; width: 100%; }
/* Day headings are plain h2 of the site scale (1.25rem/800, capitals); only the spacing is ours (Dimas, 2026-11-02, SHOW-187). */
.show-info-day-title { margin: 0 0 0.5rem; overflow-wrap: anywhere; }
.show-info-list { list-style: none; margin: 0; padding: 0; }
.show-info-list li { align-items: baseline; border-top: 1px solid var(--border-highlight); display: flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; overflow-wrap: anywhere; padding: 0.4rem 0; }
.show-info-list li:first-child { border-top: 0; padding-top: 0; }
.show-info-time { color: var(--text-secondary); font-variant-numeric: tabular-nums; min-width: 3rem; }
.show-info-award { color: var(--text-secondary); flex: 0 0 8.5rem; max-width: 100%; }
/* Wide enough for the longest award on one line ("Найкраща португальська порода")
   wherever the row has room; only a phone wraps it (Dimas, 2026-11-02, SHOW-187). */
@media (min-width: 600px) { .show-info-award { flex-basis: 16rem; } }
.show-info-event { border-top: 1px solid var(--border-highlight); padding: 0.5rem 0; }
.show-info-event:first-of-type { border-top: 0; padding-top: 0; }
.show-info-event-name { font-weight: 600; overflow-wrap: anywhere; }
.show-info-event-line { color: var(--text-secondary); font-size: 0.88rem; margin-top: 0.15rem; overflow-wrap: anywhere; }
.show-info-badge { border: 1px solid var(--border-highlight); border-radius: 999px; font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.5rem; white-space: nowrap; }

.schedule-view-switch {
    display: flex;
    padding: 0.25rem;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    flex-shrink: 0;
}

.schedule-view-option, .schedule-date-tab {
    color: var(--text-secondary);
    text-decoration: none;
    font: 700 0.78rem var(--font-display);
    transition: var(--transition-premium);
}

.schedule-view-option { padding: 0.4375rem 0.625rem; border-radius: 6px; }
.schedule-view-option.active { color: #fff; background: var(--accent-primary); }
/* The same switch made of buttons (the catalogue's Males / Females, DIM-728):
   without this the browser's own button border and background show through. */
button.schedule-view-option { border: 0; background: none; cursor: pointer; line-height: inherit; }
button.schedule-view-option.active { background: var(--accent-primary); }

/* One row: the day switcher on the left, the view switcher on the right. */
.schedule-tools { align-items: center; display: flex; flex-wrap: nowrap; gap: 0.75rem; justify-content: space-between; margin-bottom: 20px; }
.schedule-tools .schedule-view-switch { flex: 0 0 auto; margin-left: auto; }
.schedule-date-tabs { display: flex; flex: 0 1 auto; gap: 0.5rem; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.schedule-date-tabs::-webkit-scrollbar { display: none; }
.schedule-date-tab { min-width: 55px; padding: 0.5rem 0.75rem; text-align: center; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 10px; }
.schedule-date-tab span { display: block; font-size: 0.75rem; text-transform: uppercase; }
.schedule-date-tab strong { display: block; color: var(--text-primary); font-size: 1rem; }
.schedule-date-tab.active { border-color: var(--accent-primary); background: var(--accent-glow); color: var(--accent-text); }
.schedule-date-tab.active span { color: var(--bg-base); }

.schedule-ring-filter { display: grid; gap: 0.375rem; grid-auto-columns: 1fr; grid-auto-flow: column; margin-bottom: 8px; width: 100%; }
.schedule-ring-filter-btn { align-items: center; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: inline-flex; font: 700 .78rem var(--font-display); justify-content: center; overflow: hidden; padding: 0.375rem 0.25rem; transition: var(--transition-premium); white-space: nowrap; }
.schedule-ring-filter-btn .ring-word { margin-right: 5px; opacity: .5; } /* "Ring" / "R" recede, the number reads (Dimas, 2026-10-19) */
/* Short of room the gap goes, then the word with it (DIM-786). */
.schedule-ring-filter.is-tight .ring-word { margin-right: 0; }
.schedule-ring-filter-btn .ring-word:empty { display: none; }
.schedule-ring-filter-btn:hover { border-color: var(--accent-primary); color: var(--accent-text); }
.schedule-ring-filter-btn.active { background: var(--accent-primary); border-color: var(--accent-primary); color: #fff; }
.schedule-ring-filter-btn.past { opacity: .4; }
/* Class names are longer than ring numbers. One row of full names; when that
   does not fit, one row of short ones (is-short, set by fitClassLabels() the
   way "Ring" becomes "R"); only when even those do not fit, two rows. */
.catalogue-class-short { display: none; }
.catalogue-class-filter.is-short .catalogue-class-full { display: none; }
.catalogue-class-filter.is-short .catalogue-class-short { display: inline; }
.catalogue-class-filter.is-short { gap: 0.25rem; }
.catalogue-class-filter.is-short .schedule-ring-filter-btn { padding-left: 0.125rem; padding-right: 0.125rem; }
/* Two even rows: fitClassLabels() sets the column count to half the buttons. */
.catalogue-class-filter.is-wrapped { grid-auto-flow: row; }
/* Each filter row of the catalogue in its own frame, like the Males / Females
   switch, so rings and classes read as two choices and not one block. */
.catalogue-filter-frame { box-sizing: border-box; padding: 0.25rem; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 10px; margin-bottom: 0.625rem; }

/* Free-text quick search sitting right under the ring row. */
.schedule-search { margin-bottom: 20px; position: relative; width: 100%; }
/* Compact on purpose: smaller text, room on the right for the clear button. */
.schedule-search-input { font-size: .85rem; font-weight: 500; padding: 0.5625rem 2.125rem 0.5625rem 0.75rem; width: 100%; }
.schedule-search-input::-webkit-search-cancel-button { display: none; }
/* iOS Safari zooms the page into any field whose text is under 16px, and the
   layout jumps. On touch screens every field is 16px; pinch-zoom stays
   available, which maximum-scale=1 would take away on Android. */
@media (hover: none) and (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]), select, textarea { font-size: 16px !important; }
}
/* An icon, not the "×" character: the glyph sits on the font's baseline and stood
   about 2px below the field's middle (Dimas, 2026-10-31). */
.schedule-search-clear { align-items: center; background: none; border: 0; color: var(--text-muted); cursor: pointer; display: flex; justify-content: center; padding: 0.25rem 0.5rem; position: absolute; right: 4px; top: 50%; transform: translateY(-50%); }
.schedule-search-clear[hidden] { display: none; }
.schedule-search-clear .action-icon { height: 1rem; stroke-width: 2.5; width: 1rem; }
.schedule-search-clear:hover { color: var(--accent-text); }
.schedule-search-empty { color: var(--text-secondary); font-size: .85rem; margin: 0 0 20px; text-align: center; }
.is-filtered-out { display: none !important; }

.schedule-ring-tables { display: grid; gap: 1.625rem; }
.schedule-ring-table { min-width: 0; }
/* Two rings side by side once the wider container has room (Dimas, 2026-10-23).
   The by-group view keeps one column: its tables mix rings and run long. */
@media (min-width: 960px) {
    .schedule-ring-tables:not(.schedule-group-tables) { align-items: start; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.schedule-ring-table h2 { align-items: baseline; color: var(--text-primary); display: flex; flex-wrap: wrap; font: 800 1.05rem var(--font-display); gap: 0.25rem 0.625rem; margin: 0 0 10px; }
.schedule-ring-table h2 small { color: var(--text-secondary); font: 600 .82rem var(--font-display); }
.schedule-judge-link { text-decoration: none; }
.schedule-judge-link:hover { text-decoration: underline; }
.schedule-table-wrap { overflow-x: auto; border: 1px solid var(--border-color); border-radius: var(--radius-md); background: var(--bg-surface); box-shadow: var(--shadow-premium); }
/* Fixed layout, or every ring table sizes its columns to its own longest breed
   and the day reads as a pile of unrelated tables instead of one list. */
.schedule-table { width: 100%; border-collapse: collapse; table-layout: fixed; text-align: left; }
.schedule-table th:first-child, .schedule-table td:first-child { width: max(84px, 5.2rem); }
.schedule-table th:last-child, .schedule-table td:last-child { width: 76px; }
/* The catalogue view (DIM-715): a class on the left, its numbers on the right,
   wrapping as many lines as a big class needs. */
.catalogue-view-exposition { margin: 0 0 -0.75rem; color: var(--text-secondary); font-size: .9rem; }
.catalogue-view-exposition strong { color: var(--text-primary); }
.catalogue-table td:first-child { width: 46%; }
.catalogue-table td:last-child { width: auto; }
.catalogue-table td { vertical-align: top; padding-top: 0.375rem; padding-bottom: 0.375rem; }
.catalogue-numbers { color: var(--text-primary); font-variant-numeric: tabular-nums; word-spacing: 0.35em; }
/* The catalogue page (DIM-728): a class heading, then one row per dog — its
   number on the left, its name and what the catalogue says of it on the right. */
.catalogue-group { display: contents; }
/* Three day tabs and three groupings do not fit one phone line: they wrap,
   rather than squeezing the days into a strip that scrolls. The dog table is
   laid out automatically: fixed layout took its widths from the class heading
   that spans both columns and gave the number half the row. */
.catalogue-tools { flex-wrap: wrap; }
/* Folded breeds: the heading is the button, the dogs show when it is open or
   when a search matched inside it. */
.catalogue-breed:not(.is-open):not(.is-searching) .catalogue-breed-body { display: none; }
.catalogue-breed h2 { margin: 0; }
.catalogue-breed-toggle { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.5rem; width: 100%; padding: 0.25rem 0; font: inherit; color: inherit; }
.catalogue-breed-toggle::before { content: '▸'; color: var(--text-muted); transition: transform .15s; display: inline-block; }
.catalogue-breed.is-open .catalogue-breed-toggle::before, .catalogue-breed.is-searching .catalogue-breed-toggle::before { transform: rotate(90deg); }
.catalogue-breed-toggle:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
.catalogue-breed-toggle small { color: var(--text-secondary); font-weight: 400; }
.schedule-table.catalogue-dogs { table-layout: auto; }
.schedule-table.catalogue-dogs .catalogue-class-row th { width: auto; }
.catalogue-group[hidden] { display: none; }
.catalogue-dogs .catalogue-class-row th { padding: 0.5rem 0.75rem 0.25rem; font-size: .72rem; letter-spacing: .03em; text-transform: uppercase; color: var(--text-muted); background: var(--bg-elevated, transparent); text-align: left; }
.catalogue-dogs td { vertical-align: top; padding-top: 0.375rem; padding-bottom: 0.375rem; }
.schedule-table.catalogue-dogs td.catalogue-dog-no { width: 1%; white-space: nowrap; padding-right: 0.75rem; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text-primary); }
.schedule-table.catalogue-dogs td.catalogue-dog { width: auto; }
.catalogue-dog-name { display: block; color: var(--text-primary); font-weight: 600; overflow-wrap: anywhere; }
.catalogue-dog-meta { display: block; color: var(--text-secondary); font-size: .8rem; overflow-wrap: anywhere; }
.catalogue-dog-people { color: var(--text-muted); }
/* Titles as tags (DIM-730). Every tag looks the same, whether or not we know
   what it stands for (Dimas, 2026-10-12); only a known one opens its meaning. */
.catalogue-titles { display: flex; flex-wrap: wrap; gap: 0.25rem; margin: 0.25rem 0 0.125rem; }
.catalogue-title { all: unset; box-sizing: border-box; display: inline-block; padding: 0.0625rem 0.375rem; border: 1px solid var(--border-color); border-radius: 999px; font-size: .7rem; font-weight: 600; line-height: 1.5; color: var(--accent-text); border-color: var(--accent-primary); font-variant-numeric: tabular-nums; white-space: nowrap; }
button.catalogue-title { cursor: pointer; }
button.catalogue-title:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.catalogue-title-explain { display: block; color: var(--text-secondary); font-size: .78rem; margin-top: 0.125rem; }
.catalogue-title-explain[hidden] { display: none; }

.schedule-table th {
    padding: 0.5rem 0.5rem;
    font-size: .64rem;
    letter-spacing: .03em;
    color: var(--text-muted);
    text-transform: uppercase;
    background: var(--bg-card);
}
/* A fixed column is a promise the header has to keep. "Собаки" set wide and
   spaced is 64px of min-content against a 58px column, and the table pushed
   the extra six pixels out sideways: wrapping is allowed here so no
   translation of a heading can ever hand the table a horizontal scrollbar. */
.schedule-table th { overflow-wrap: anywhere; }
.schedule-table td { padding: 0.1875rem 0.5rem; border-top: 1px solid var(--border-color); color: var(--text-secondary); font-size: .86rem; }
@media (hover: hover) { .schedule-table tr:hover td { background: var(--tint-subtle); } }
.schedule-table tr.past td { opacity: .4; }
/* The row in the ring says so by being lit, not by wearing a tag. A badge on
   the row competed with the breed name for the same glance; the colour of the
   row is read before either of them. */
.schedule-table tr.now td { background: rgba(var(--accent-primary-rgb), .12); }
.schedule-table tr.now td:first-child { box-shadow: inset 3px 0 0 var(--accent-primary); }
.schedule-now-badge { background: var(--accent-primary); color: var(--bg-base); font-size: 0.65rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.125rem 0.375rem; border-radius: 4px; margin-left: 8px; display: inline-block; vertical-align: middle; line-height: 1; }
/* The same badge, paler: a breed still to come says how long, and must not
   compete with the one that is actually in the ring. */
.schedule-now-badge.is-ahead {
    background: rgba(var(--accent-primary-rgb), .22);
    color: var(--text-secondary);
    /* "+1h23m" is a reading, not a label: upper case mangles the h and the m. */
    text-transform: none;
}

.schedule-next-badge { background: transparent; color: var(--text-muted); border: 1px solid var(--border-color); font-size: 0.65rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.0625rem 0.3125rem; border-radius: 4px; margin-left: 8px; display: inline-block; vertical-align: middle; line-height: 1; }
.schedule-table-time { color: var(--accent-text) !important; font: 800 .95rem var(--font-display); white-space: nowrap; }
.schedule-table-breed { color: var(--text-primary) !important; font: 600 .95rem var(--font-display); word-wrap: break-word; word-break: break-word; white-space: normal; }

@media (max-width: 500px) {
    .schedule-table th {
        padding: 0.5rem 0.5rem;
        font-size: .64rem;
        letter-spacing: .03em;
    }
    .schedule-table th:first-child, .schedule-table td:first-child {width: max(62px, 4rem); padding: 0.1875rem 0.1875rem 0.1875rem 0.5rem; }
    .schedule-table th:last-child, .schedule-table td:last-child { width: 66px; }
}

.schedule-empty-state { margin-top: 32px; text-align: center; }
.schedule-empty-state p a { font-weight: 600; }
/* "Choose another show" is a full-width secondary button, at least 44px tall (Dimas, SHOW-127). */
.schedule-empty-state p { margin-top: 1rem; }
.schedule-empty-state p a.btn-premium { color: var(--text-primary); font-weight: 700; min-height: 44px; }
/* The notification prompt under it (SHOW-70). */
.schedule-empty-banner { margin: 1rem 0 1.5rem; }

@media (max-width: 560px) {
    .schedule-heading { align-items: flex-start; flex-direction: column; }
    .schedule-heading-main { align-self: stretch; }
    .schedule-tools { gap: 0.5rem; }
    .schedule-date-tab { min-width: 46px; padding: 0.4375rem 0.5625rem; }
    .schedule-view-option { padding: 0.4375rem 0.5rem; }
    .bar-tab { padding: 0.3125rem 0.1875rem 0.375rem; font-size: .62rem; }
    .bar-tab-hub { height: 64px; margin: -30px 0.375rem 0; padding: 0; width: 64px; }
}

.import-show-preview {
    background-color: var(--tint-subtle);
    border: 1px solid var(--border-color);
    padding: 0.75rem;
    border-radius: var(--radius-sm);
    margin-bottom: 12px;
}

.import-show-preview-label {
    font-size: 0.8rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    font-weight: bold;
    letter-spacing: 0.05em;
}

.import-show-preview-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    margin-top: 4px;
    color: var(--accent-text);
}

/* Import Tabs */
.import-tabs {
    display: flex;
    gap: 0.25rem;
    margin-bottom: 16px;
    background-color: var(--bg-card);
    border-radius: var(--radius-sm);
    padding: 0.25rem;
    border: 1px solid var(--accent-glow)
}

.import-tab {
    flex: 1;
    padding: 0.625rem 0.75rem;
    border: none;
    background: none;
    color: var(--text-secondary);
    font-family: var(--font-body);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    border-radius: 6px;
    transition: var(--transition-premium);
}

.import-tab:hover {
    color: var(--text-primary);
    background-color: var(--bg-overlay);
}

.import-tab.active {
    background-color: var(--accent-primary);
    color: white;
}

/* Settings → Usage: the tab bar is links and scrolls sideways inside itself */
.usage-tabs { flex-wrap: wrap; }
@media (max-width: 767px) {
    /* On a phone one row that scrolls sideways, without the scrollbar. */
    .usage-tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
    .usage-tabs::-webkit-scrollbar { display: none; }
}
.usage-tabs .import-tab { flex: 0 0 auto; text-align: center; text-decoration: none; white-space: nowrap; }
.usage-panel[hidden] { display: none; }

/* Import Panels */
.import-panel {
    display: none;
}

.import-panel.active {
    display: block;
}

/* Ring correction dialog: the three answers and the buttons under them */
.ring-update-answers {
    margin-top: 1rem;
}

.ring-update-answers .import-tabs {
    margin-bottom: 0.75rem;
}

.ring-update-save {
    margin-top: 1.5rem;
}

/* Import Hints */
.import-field-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    font-weight: normal;
    display: block;
    margin-top: 4px;
    margin-bottom: 8px;
    line-height: 1.5;
}

/* Import Result Feedback */
.import-result {
    margin-top: 12px;
    padding: 0;
    font-size: 0.85rem;
    border-radius: var(--radius-sm);
    transition: var(--transition-premium);
}

.import-result:empty {
    display: none;
}

/* Pre-import page checks: what the page must contain, and what it does. */
.import-note { font-size: .74rem; margin-top: 8px; opacity: .85; word-break: break-all; }
.import-problems { display: grid; gap: 0.3125rem; font-size: .78rem; list-style: none; margin: 10px 0 0; padding: 0; }
.import-problems li { padding-left: 1rem; position: relative; }
.import-problems li::before { content: "•"; left: 3px; position: absolute; }
.import-checks ul { display: grid; gap: 0.25rem; list-style: none; margin: 8px 0 0; padding: 0; }
.import-checks li { align-items: baseline; display: flex; font-size: .72rem; gap: 0.5rem; justify-content: space-between; }
.import-checks li small { color: var(--text-muted); flex: 0 0 auto; }
.import-checks .check-ok { color: var(--color-friends); }
.import-checks .check-fail { color: var(--color-my-dogs); }

/* Root-only diagnostics, shown under an error toast or an import result. */
.import-detail, .toast-detail { margin-top: 8px; }
.import-detail summary, .toast-detail summary { cursor: pointer; font: 700 .68rem var(--font-display); letter-spacing: .06em; opacity: .8; text-transform: uppercase; }
.import-detail pre, .toast-detail pre {
    background: rgba(0,0,0,.28);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-secondary);
    font-size: .7rem;
    line-height: 1.45;
    margin-top: 6px;
    max-height: 220px;
    overflow: auto;
    padding: 0.5rem 0.625rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.import-result-success {
    padding: 0.75rem;
    background-color: rgba(var(--color-friends-rgb), 0.1);
    border: 1px solid rgba(var(--color-friends-rgb), 0.3);
    color: var(--color-friends);
}

.import-result-error {
    padding: 0.75rem;
    background-color: rgba(var(--color-my-dogs-rgb), 0.1);
    border: 1px solid rgba(var(--color-my-dogs-rgb), 0.3);
    color: var(--color-my-dogs);
}
button.link-button {
    appearance: none;
    border: 0;
    padding: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Breed CRUD specific styles */
.breed-search-card {
    padding: 0.75rem 1rem;
    margin-bottom: 16px;
}
.breed-search-input {
    width: 100%;
    font-size: 0.9rem;
}
/* Name and actions only: two columns need no horizontal scroll floor. */
#breeds-table { min-width: 0; }
#breeds-table td.user-actions, #breeds-table th:last-child { width: 1%; }
.breed-edit-layout {
    display: grid;
    gap: 1rem;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 0.85fr);
    align-items: start;
}
/* Same reason as the track above: a grid item defaults to a min-content floor,
   so any card holding something wide would widen the page instead of scrolling
   or wrapping inside itself. */
.breed-edit-layout > * { min-width: 0; }
/* Every name the breed answers to, in one list: the catalogue's own first, then
   the aliases. Each row is a button because each row opens an editor, and a
   thing you click is a control whether or not it looks like one. */
.breed-name-list {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin-top: 16px;
}
.breed-name-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-primary);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.breed-name-item:hover { border-color: var(--accent-primary); }
.breed-name-item-text { min-width: 0; overflow-wrap: anywhere; font-size: .85rem; }
.breed-name-item-main .breed-name-item-text { font-weight: 700; }
.breed-name-item-tags {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 0.5rem;
}
.breed-name-item-tags small { font-size: .7rem; color: var(--text-secondary); }
/* The two things a name can have done to it that are not a save, side by side
   under the form: each is its own submission, so each is its own form. */
.breed-name-modal-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    margin-top: 16px;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border-color);
}
.breed-name-modal-actions .btn-premium { width: auto; font-size: .72rem; padding: 0.5625rem 0.8125rem; }
/* The one name that is the breed rather than a way of finding it. */
.breed-name-badge {
    padding: 0.125rem 0.5rem;
    border-radius: 4px;
    background: var(--accent-glow);
    color: var(--bg-card);
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}
/* Aliases are added through a modal, so the card header carries the button. */
.breed-alias-card-head {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: space-between;
}
.breed-alias-card-head .settings-card-title { margin-bottom: 0; }
.breed-alias-card-head .btn-premium { font-size: .72rem; padding: 0.5625rem 0.8125rem; white-space: nowrap; width: auto; }
.alias-lang {
    background: var(--bg-overlay);
    padding: 0.125rem 0.375rem;
    border-radius: 4px;
    font-size: 0.75rem;
    color: var(--text-secondary);
    text-transform: uppercase;
}
/* Two lines above the catalogue: what the run is doing, and where the
   catalogue stands. The second is permanent, so the block never collapses and
   the table below it does not jump when a fetch starts or ends. */
.fci-run-status { margin-bottom: 12px; }
.fci-run-line { margin: 0; font-size: .78rem; }
.fci-run-line + .fci-run-line { margin-top: 2px; }
.fci-run-line b { color: var(--text-primary); font-weight: 700; }
.fci-run-line[hidden] { display: none; }

/* Catalogue row: a 35px slot, then the name. The slot is always there — with a
   picture, with the paw when the breed has FCI data but no picture, and empty
   when it has neither — so every name in the table starts at the same x. */
.breed-name-cell {
    display: flex;
    align-items: center;
    gap: 0.625rem;
}
/* The tick leads the row in a column of its own, so the heading over the names
   labels the names rather than the checkbox. */
.breed-check, .breed-head-select input {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--accent-primary);
    cursor: pointer;
}
#breeds-table th.breed-head-select, #breeds-table td.breed-cell-select { width: 1%; padding-right: 0; }
/* The picture has its own column, so "Breed Name" stands over the names. */
#breeds-table th.breed-head-thumb, #breeds-table td.breed-cell-thumb { width: 1%; padding-right: 0; }
#breeds-table th.breed-head-group, #breeds-table td.breed-cell-group { width: 1%; white-space: nowrap; }
#breeds-table th.breed-head-std, #breeds-table td.breed-cell-std { width: 1%; white-space: nowrap; }
/* A heading you can click is a button, so it is one — keyboard and all. */
.breed-head-sort button,
.table-head-sort button {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    cursor: pointer;
}
.breed-head-sort button:hover,
.table-head-sort button:hover { color: var(--text-primary); }
.breed-sort-arrow,
.table-sort-arrow { font-size: .6rem; color: var(--accent-text); }
.merge-choice-list {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    max-height: 280px;
    overflow-y: auto;
    margin-bottom: 4px;
}
.merge-choice {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5625rem 0.6875rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    cursor: pointer;
    font-size: .82rem;
}
.merge-choice:hover { border-color: var(--accent-primary); }
.merge-choice input { width: auto; margin: 0; accent-color: var(--accent-primary); }
.merge-choice:has(input:checked) { border-color: var(--accent-primary); }
.breed-delete-form { margin-top: 16px; padding-top: 0.875rem; border-top: 1px solid var(--border-color); }
.breed-delete-form .btn-premium { width: auto; font-size: .72rem; padding: 0.5625rem 0.8125rem; }
.breed-delete-note { margin-top: 16px; padding-top: 0.875rem; border-top: 1px solid var(--border-color); font-size: .72rem; }
/* The name and its note are one column beside the picture, not siblings of it.
   As flex items of the row they could not shrink below their own text, so a
   long name wrapped underneath the picture instead of beside it — min-width:0
   is what lets the text wrap inside the cell it was given. */
.breed-name-body { min-width: 0; flex: 1 1 auto; }
.breed-name-body strong { overflow-wrap: anywhere; }
.breed-thumb {
    flex: 0 0 auto;
    width: 35px;
    height: 35px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 7px;
    overflow: hidden;
}
/* Not square? Fill the square and crop, rather than letterbox the dog. The paw
   is excluded — it is a placeholder sitting in the slot, not the picture. */
.breed-thumb img:not(.breed-paw) { width: 100%; height: 100%; object-fit: cover; display: block; }
.breed-thumb .breed-paw { display: none; width: 22px; height: 22px; object-fit: contain; }
.breed-thumb-photo { background: var(--bg-overlay); }
.breed-thumb-empty { background: rgba(var(--color-important-rgb), .1); }
.breed-thumb-empty .breed-paw { display: block; }
.breed-fci-note { font-size: .7rem; color: var(--text-secondary); }
/* The group has its own column now, so the tag only has to be a tag. */
.breed-group-tag {
    display: inline-block;
    padding: 0.1875rem 0.5rem;
    border: 1px solid var(--accent-glow);
    border-radius: var(--radius-sm);
    color: var(--accent-glow);
    font-weight: 700;
    font-size: .68rem;
    letter-spacing: .04em;
    white-space: nowrap;
}
.breed-group-tag[hidden] { display: none; }
/* The standard body, in the same shape as the group but quieter: it is the
   same word down most of the column, so it reads as a marker rather than
   competing with the group beside it. Empty until the breed has actually been
   read from that body, so the column shows what is confirmed. */
.breed-std-tag {
    display: inline-block;
    padding: 0.1875rem 0.5rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-weight: 700;
    font-size: .66rem;
    letter-spacing: .04em;
    white-space: nowrap;
}
.breed-std-tag[hidden] { display: none; }
/* How many of the six names the breed carries. Deliberately plain until it is
   complete: a column of green ticks down a mostly-translated catalogue says
   nothing, while the few incomplete rows are what the eye should catch. */
.breed-cell-langs { white-space: nowrap; }
.breed-lang-count {
    display: inline-block;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    font-size: .78rem;
    font-weight: 600;
}
.breed-lang-count.is-complete { color: var(--text-muted); }
/* English and nothing else -- what a fresh import leaves behind, and the set
   worth running a translation hunt over first. */
.breed-lang-tag {
    display: inline-block;
    margin-left: 6px;
    padding: 0.125rem 0.4375rem;
    border-radius: var(--radius-sm);
    background: color-mix(in srgb, var(--accent-color) 16%, transparent);
    color: var(--accent-color);
    font-weight: 700;
    font-size: .62rem;
    letter-spacing: .04em;
    white-space: nowrap;
}
/* The summary sits above the table with its filter beside it, so the count and
   the way to act on it are one thing rather than two. */
.breed-translation-card {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    justify-content: space-between;
}
.breed-translation-card .settings-intro { margin: 0; }
.breed-translation-card .btn-premium.is-active {
    border-color: var(--accent-color);
    color: var(--accent-color);
}

/* "This one needs a person." Sits before the group tag and takes the auto
   margin when it is showing, so the pair stays against the right edge. */
.breed-status-tag {
    border-radius: var(--radius-sm);
    flex: 0 0 auto;
    margin-left: auto;
    padding: 0 0.375rem 0.0625rem 0.375rem;
    background: rgba(var(--color-important-rgb), .14);
    color: var(--text-primary); /* (Dimas, 2026-10-31, SHOW-127) */
    font: 700 .68rem var(--font-display);
    letter-spacing: .04em;
    white-space: nowrap;
}
.breed-status-tag[hidden] { display: none; }
.breed-fci-note-error { color: var(--color-my-dogs); }
.breed-fci-note-warn { color: var(--color-important); }

/* The FCI card reads as a profile: portrait, official name, group and standard
   number on one line, the source link at its foot. Editing happens in a modal,
   so nothing here is a form control. */
.fci-profile {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    margin-top: 4px;
}
.fci-profile-photo {
    flex: 0 0 auto;
    width: 96px;
    height: 96px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-overlay);
    overflow: hidden;
}
.fci-profile-photo img { width: 100%; height: 100%; object-fit: cover; }
.fci-profile-photo-empty { font-size: .68rem; color: var(--text-secondary); text-align: center; padding: 0 0.375rem; }
.fci-profile-facts {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
}
/* Whose name it is, then the name. The label leads the line rather than sitting
   under the numbers, because "Podengo Português" is what the CPC calls this
   breed and the FCI would call it something else. */
.fci-profile-title {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    min-width: 0;
}
.fci-profile-title strong { font-size: 1rem; color: var(--text-primary); word-break: break-word; }
.fci-profile-title strong:empty::before { content: '—'; color: var(--text-secondary); }
.fci-profile-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem 0.875rem;
    font-size: .78rem;
    color: var(--text-secondary);
}
.fci-profile-meta em { font-style: normal; font-weight: 600; color: var(--text-primary); }
.fci-profile-meta em:empty::before { content: '—'; font-weight: 400; color: var(--text-secondary); }
.fci-profile-hint { font-size: .72rem; color: var(--text-secondary); }
/* Whose standard this is, and the button that reads it — one line under the
   group and the number, because the name is what says which site Fetch asks. */
.fci-profile-standard {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.625rem;
    margin-top: 2px;
}
.fci-standard-name {
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--text-primary);
    background: var(--bg-overlay);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 0.1875rem 0.5625rem;
}
.fci-profile-standard .btn-premium { width: auto; font-size: .72rem; padding: 0.4375rem 0.75rem; }
/* The undo is a form, so that it is a POST with a token like every other write.
   It still has to sit in the row as if it were just the button inside it. */
.fci-unlink-form { display: inline-flex; }
.fci-unlink-form[hidden] { display: none; }
.fci-profile-footer {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.625rem;
    margin-top: 16px;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border-color);
}
.fci-profile-footer small { font-size: .7rem; color: var(--text-secondary); }
.fci-profile-footer .btn-premium { margin-left: auto; width: auto; font-size: .72rem; padding: 0.5625rem 0.8125rem; }
.fci-profile-link { font-size: .78rem; color: var(--accent-text); text-decoration: none; }
.fci-profile-link:hover { text-decoration: underline; }
/* Group and standard number are one line in the editor too. */
.fci-form-row { display: flex; gap: 0.75rem; }
.fci-form-row > label { flex: 1 1 0; min-width: 0; }
.fci-remove-image {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: .78rem;
}
.fci-remove-image input { width: auto; margin: 0; }

/* FCI lookup: the verdict line, then the ranked matches when the FCI's
   "contains" search returned more than this breed. */
.fci-lookup-status {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 12px 0;
    padding: 0.625rem 0.75rem;
    border-radius: 8px;
    background: var(--bg-overlay);
    font-size: .78rem;
    color: var(--text-secondary);
}
.fci-lookup-status strong { color: var(--text-primary); font-size: .8rem; }
.fci-lookup-status small { font-size: .72rem; line-height: 1.4; word-break: break-word; }
.fci-lookup-ok strong { color: var(--accent-text); }
.fci-lookup-warn strong { color: var(--color-my-dogs); }
.fci-lookup-error strong { color: var(--color-my-dogs); }
.fci-lookup-matches {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin-bottom: 12px;
    max-height: 260px;
    overflow-y: auto;
}
.fci-match {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    width: 100%;
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
}
.fci-match:hover { border-color: var(--accent-primary); }
.fci-match strong { font-size: .8rem; }
.fci-match small { font-size: .7rem; color: var(--text-secondary); }
.breed-name-link {
    color: inherit;
    text-decoration: none;
}
.breed-name-link:hover {
    color: var(--accent-text);
}

@media (max-width: 768px) {
    .breed-edit-layout {
        /* minmax(0, …), not 1fr: a plain 1fr track cannot shrink below its
           content's min-content width, so anything wide inside a card — the
           alias table this once held, a long official name, an image — became
           the column's floor and pushed the whole page sideways on anything
           narrower. Wide content scrolls or wraps inside its own card instead. */
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Pull to Refresh */
.ptr-indicator {
    position: fixed;
    top: -50px;
    left: 0;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 50px;
    z-index: var(--z-notice);
    pointer-events: none;
    transition: transform 0.2s ease;
}
.ptr-indicator .ptr-box {
    background: var(--bg-card);
    box-shadow: var(--shadow-premium);
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    color: var(--text-primary);
    font-size: 1.2rem;
    transition: transform 0.2s ease;
    border: 1px solid var(--border-color);
}
.ptr-indicator.ptr-ready .ptr-box {
    transform: rotate(180deg);
}
.ptr-indicator.ptr-loading .ptr-box {
    animation: ptr-spin 1s linear infinite;
    transform: rotate(0deg);
}
@keyframes ptr-spin {
    100% { transform: rotate(360deg); }
}


/* --- Users Bulk Actions & FAB --- */
.checkbox-col {
    width: 25px;
    text-align: center;
}

.users-table tbody tr.row-selected {
    background-color: rgba(var(--accent-primary-rgb), 0.1);
}

.bulk-fab-container {
    position: fixed;
    bottom: 100px;
    right: 24px;
    z-index: var(--z-modal);
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
    opacity: 0;
    pointer-events: none;
    transform: translateY(20px) scale(0.9);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.bulk-fab-container.visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0) scale(1);
}

.bulk-fab-trigger {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-color: var(--accent-primary);
    color: #fff;
    border: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.2s, background-color 0.2s;
}

.bulk-fab-trigger:hover, .bulk-fab-trigger:focus-visible {
    background-color: var(--accent-primary);
    transform: scale(1.05);
}

.bulk-fab-trigger:active {
    transform: scale(0.95);
}

.bulk-fab-menu {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 150px;
}

.bulk-menu-item {
    background: none;
    border: none;
    padding: 0.75rem 1rem;
    text-align: left;
    color: var(--text-primary);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s;
    width: 100%;
}

.bulk-menu-item:hover {
    background-color: var(--bg-surface);
}

.bulk-menu-danger {
    color: var(--color-my-dogs);
}

.bulk-menu-danger:hover {
    background-color: rgba(var(--color-my-dogs-rgb), 0.1);
}

/* --- User Card Modal --- */
.user-card-trigger {
    background: none;
    border: none;
    padding: 0;
    color: var(--text-primary);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    text-decoration-color: transparent;
    transition: text-decoration-color 0.2s;
}

.user-card-trigger:hover {
    text-decoration-color: var(--accent-primary);
}

.user-card-container {
    max-width: 400px;
}

.user-card-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 24px;
}

.user-card-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    background-color: var(--bg-base);
    border: 1px solid var(--border-color);
}

.user-card-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    font-weight: bold;
    color: var(--text-secondary);
}

.user-card-info {
    flex-grow: 1;
}

.user-card-name {
    margin: 0 0 4px 0;
    font-size: 1.125rem;
    color: var(--text-primary);
}

.user-card-email {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.user-card-details {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.user-card-detail-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem;
    background-color: var(--bg-base);
    border-radius: 8px;
    border: 1px solid var(--border-color);
}

.detail-label {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.detail-value {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-primary);
}

.user-badge {
    padding: 0.25rem 0.5rem;
    border-radius: 12px;
    font-size: 0.75rem;
    font-weight: 600;
}

.user-badge.verified {
    background-color: rgba(var(--color-friends-rgb), 0.1);
    color: var(--color-friends);
}

.user-badge.pending {
    background-color: rgba(var(--color-important-rgb), 0.1);
    color: var(--text-primary); /* (Dimas, 2026-10-31, SHOW-127) */
}

/* ==========================================================================
   Version history (/versionlog/)
   Rendered from settings/changelog.php. The page used to carry these rules as
   inline styles emitted by a markdown pass in PHP.
   ========================================================================== */
.changelog { margin-top: 20px; }

.changelog-title {
    font-family: var(--font-display);
    font-weight: 800;
    margin-bottom: 20px;
    padding-bottom: 0.625rem;
    border-bottom: 1px solid var(--border-color);
}

.changelog-release + .changelog-release { margin-top: 28px; }

.changelog-version {
    display: flex;
    align-items: baseline;
    gap: 0.625rem;
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    text-transform: none;
    color: var(--accent-text);
    margin-bottom: 10px;
}

.changelog-version time {
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--text-secondary);
}

.changelog-changes {
    padding-left: 1.25rem;
    margin: 0;
}

.changelog-changes li {
    margin-bottom: 8px;
    color: var(--text-secondary);
    line-height: 1.5;
}

.changelog-empty { color: var(--text-secondary); }
.changelog-lede { color: var(--text-secondary); font-size: .88rem; line-height: 1.6; margin: 0 0 18px; }
.info-build { color: var(--text-primary); font: 700 .95rem var(--font-display); margin: 0 0 6px; }

/* The build log: one card per deploy. */
.build-entry + .build-entry { margin-top: 12px; }
.build-head { align-items: baseline; display: flex; flex-wrap: wrap; gap: 0.625rem; }
.build-head strong { font: 700 1rem var(--font-display); }
.build-version { background: rgba(var(--accent-primary-rgb), .12); border-radius: var(--radius-sm); color: var(--accent-text); font: 700 .78rem var(--font-display); padding: 0.125rem 0.5rem; }
.build-head time, .build-count { color: var(--text-muted); font-size: .78rem; }
/* Check source: the icon turns while the request is out, and the verdict stays
   beside the button with its evidence folded away behind it. */
.expo-show-check.is-checking .action-icon { animation: expo-check-spin 1s linear infinite; transform-origin: 50% 50%; }
@keyframes expo-check-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    /* A turning icon is the only sign the press was heard, so it does not stop
       moving -- it pulses instead of spinning. */
    .expo-show-check.is-checking .action-icon { animation: expo-check-pulse 1.4s ease-in-out infinite; }
    @keyframes expo-check-pulse { 50% { opacity: .35; } }
}
.expo-check-result { align-items: baseline; display: inline-flex; flex-wrap: wrap; font-size: .78rem; gap: 0.5rem; }
.expo-check-result strong { font: 700 .78rem var(--font-display); }
.expo-check-result[data-check-verdict="unchanged"] strong { color: var(--color-friends); }
.expo-check-result[data-check-verdict="changed"] strong { color: var(--accent-text); }
.expo-check-result[data-check-verdict="error"] strong { color: var(--color-my-dogs); }
.expo-check-result[data-check-verdict="idle"] strong { color: var(--text-muted); }
.expo-check-detail summary { color: var(--text-muted); cursor: pointer; }
.expo-check-detail ul { color: var(--text-muted); font-size: .74rem; line-height: 1.5; margin: 6px 0 0; padding-left: 1rem; }
.expo-check-detail li { overflow-wrap: anywhere; }
/* The check's evidence sits in the card body, below the sticky header, so the
   fold-out grows the card and pushes the day list down instead of painting over
   it. Its own strip so the boundary reads. */
.expo-check-evidence { padding: 0.625rem 0.9375rem; background: var(--bg-elevated, var(--tint-subtle)); border-bottom: 1px solid var(--border-color); }
.expo-check-evidence:empty { display: none; }
.expo-check-evidence .expo-check-detail summary { font-size: .8rem; font-weight: 600; }

.build-note { color: var(--text-secondary); font-size: .86rem; line-height: 1.55; margin: 10px 0 0; padding-left: 1.125rem; }
.build-note li + li { margin-top: 4px; }
.build-headline { color: var(--text-muted); font-size: .78rem; margin: 8px 0 0; }
.build-notes-heading { margin: 14px 0 6px; }
.build-notes { color: var(--text-secondary); font-size: .84rem; line-height: 1.55; margin: 0; padding-left: 1.125rem; }
.build-notes-internal { color: var(--text-muted); }
.build-files { margin-top: 12px; }
.build-files summary { color: var(--text-secondary); cursor: pointer; font-size: .8rem; }
.build-files ul { color: var(--text-muted); font-family: var(--font-mono, monospace); font-size: .76rem; line-height: 1.5; margin: 8px 0 0; padding-left: 1.125rem; }
.settings-empty { color: var(--text-secondary); }

.changelog-foot {
    margin-top: 30px;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-color);
    text-align: center;
}

.changelog-foot .btn-premium { width: auto; padding: 0.625rem 1.5rem; }

/* Remote page probe (Settings → Debug). The body panel holds somebody else's
   markup as plain text, so it scrolls on both axes rather than reflowing. */
.probe-table { border-collapse: collapse; font-size: .82rem; margin-top: 16px; width: 100%; }
.probe-table th,
.probe-table td { border-bottom: 1px solid var(--border-color); padding: 0.4375rem 0.625rem; text-align: left; vertical-align: top; }
.probe-table th { color: var(--text-muted); font-weight: 600; white-space: nowrap; width: 34%; }
.probe-table td { color: var(--text-secondary); word-break: break-word; }
/* The reachability bench is a wide, many-column table, not the probe's two-column
   key/value list, so its header cells are not a fixed third of the width. Each
   entrance opens with a full-width title row above its metrics. */
.cpc-bench-table th { width: auto; white-space: nowrap; }
.cpc-bench-table .cpc-bench-head td { border-top: 2px solid var(--border-color); padding-top: 0.75rem; }
.cpc-bench-table .cpc-bench-head strong { color: var(--text-primary, var(--text-secondary)); }
.cpc-bench-table .cpc-bench-head small { color: var(--text-muted); font-weight: 400; }
/* Why a rung did not serve the page, under its title. It is the half of the
   answer the verdict column has no room for. */
.cpc-bench-table .cpc-bench-why { color: var(--color-my-dogs); font-size: .72rem; font-weight: 400; line-height: 1.45; margin-top: 4px; }
.probe-body {
    background: var(--bg-base);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-secondary);
    font: .72rem/1.5 monospace;
    max-height: 420px;
    overflow: auto;
    padding: 0.75rem;
    white-space: pre-wrap;
    word-break: break-word;
}

/* A judge's country: the flag for recognition, the code because several flags
   are indistinguishable at this size. Printed inline after the name. */
.judge-flag {
    align-items: center;
    display: inline-flex;
    gap: 0.25rem;
    margin-left: 7px;
    vertical-align: baseline;
    white-space: nowrap;
}
.judge-flag-glyph { font-size: 1.05em; line-height: 1; }
.judge-flag-code {
    background: rgba(var(--border-color-rgb), .55);
    border-radius: 4px;
    color: var(--text-muted);
    font: 600 .68rem/1 monospace;
    letter-spacing: .04em;
    padding: 0.1875rem 0.25rem;
}
.judge-card-identity h2 .judge-flag { margin-left: 8px; }

/* The show that has just finished. Shaded rather than hidden: it is behind you,
   but for a few days it is still the one being looked up. */
.recent-show-bar { opacity: .62; }
.recent-show-bar:hover,
.recent-show-bar:focus-within { opacity: 1; }
.schedule-past-badge {
    background: var(--bg-overlay);
    border-radius: 4px;
    color: var(--text-muted);
    display: inline-block;
    font-size: .65rem;
    font-weight: 800;
    letter-spacing: .05em;
    line-height: 1;
    margin-left: 8px;
    padding: 0.125rem 0.375rem;
    text-transform: uppercase;
    vertical-align: middle;
}
/* The show that has just finished is lifted out of the folded block, so it is
   already in a place of its own. It needs no dimming to say it is over — the
   tick at its front says that. */

/* Reordering a ring (administrators on the timetable, ring assistants on their
   sheet): the whole row is the handle. Nothing
   saves on drop — the bar below and its confirmation do — so the row needs no
   extra column and the breed keeps the width. */
/* The slot a dragged breed will land in: the row itself, emptied and dashed,
   while a card with its name follows the finger (Dimas, 2026-10-27). */
tr.schedule-row-dragging td {
    background: rgba(var(--accent-primary-rgb), 0.08);
    border-top: 2px dashed var(--accent-primary);
    border-bottom: 2px dashed var(--accent-primary);
    color: transparent;
}
tr.schedule-row-dragging td > * { visibility: hidden; }
tr.schedule-row-dragging-numbers { display: none; }
.schedule-drag-ghost {
    position: fixed;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    padding: 0 1rem;
    box-sizing: border-box;
    background: var(--bg-overlay);
    border: 1px solid var(--accent-primary);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
    color: var(--text-primary);
    font-weight: 600;
    pointer-events: none;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* CPC Challenge: the entrance list is dragged the same way, and says so — the
   row is the grip, so the cursor has to admit that before anyone tries. While a
   drag is running, text selection would fight the finger. */
[data-cpc-sources][data-reorderable="1"] .debug-mode-switch { cursor: grab; }
[data-cpc-sources].cpc-sources-dragging { user-select: none; }
[data-cpc-sources].cpc-sources-dragging .debug-mode-switch { cursor: grabbing; }
.debug-mode-switch.cpc-source-dragging { background: var(--bg-overlay); border-radius: 10px; opacity: .6; }

/* "Changed and not saved", perched on the bottom navigation like the offline
   banner: visible wherever the operator has scrolled to, gone when the order
   is dragged back to where it started. */
.reorder-panel {
    align-items: center;
    background: var(--bg-card);
    border-top: 1px solid var(--accent-primary);
    display: flex;
    gap: 0.75rem;
    justify-content: center;
    left: 0;
    padding: 0.625rem 0.875rem;
    position: fixed;
    right: 0;
    z-index: var(--z-notice);
}
.reorder-panel span { color: var(--text-primary); font: 600 .82rem var(--font-display); }
.reorder-panel .btn-premium { flex: 0 0 auto; width: auto; }
.reorder-question { font-weight: 700; margin-top: 12px; }

/* Deciding between names nobody could choose between automatically.
   One card per breed, one block per language, because that is the shape the
   question has: "what is this breed called in Ukrainian, given these." The two
   quiet actions are deliberately quiet — taking a name is the common answer and
   the only one that should read as a button. */
.breed-review-summary .settings-intro { margin: 0; }

.breed-review-card { margin-bottom: 16px; }

.breed-review-head {
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border-color);
}
.breed-review-head .settings-card-title { margin-bottom: 4px; }
/* The mapping's explanation, said once for the breed rather than repeated
   under every language it proposed. */
.breed-review-note {
    margin: 6px 0 0;
    color: var(--text-muted);
    font-size: .78rem;
    line-height: 1.45;
}

.breed-review-lang { padding: 0.75rem 0; }
.breed-review-lang + .breed-review-lang { border-top: 1px solid var(--border-color); }
.breed-review-lang-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 10px;
}
/* "None of these" is one of the answers, so it sits with the question rather
   than at the bottom of the page. */
.breed-review-dismiss { margin: 0; }

.breed-review-option {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.625rem;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm, 8px);
    background: rgba(var(--bg-overlay-rgb), .35);
}
.breed-review-option + .breed-review-option { margin-top: 8px; }

.breed-review-option-body { min-width: 0; }
.breed-review-name {
    display: block;
    font-family: var(--font-display, inherit);
    font-size: 1rem;
    line-height: 1.3;
}
.breed-review-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 3px;
    color: var(--text-muted);
    font-size: .72rem;
}
.breed-review-source { color: var(--text-secondary); }

.breed-review-confidence {
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
}
.breed-review-confidence-certain { color: #10B981; }
.breed-review-confidence-likely  { color: var(--accent-text); }
.breed-review-confidence-unsure  { color: var(--text-muted); }

/* .btn-premium is width:100% for the full-width forms it was written for, so
   the buttons in a row have to opt out or each one fills its own line. */
.breed-review-option-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.breed-review-option-actions form,
.breed-review-dismiss { flex: 0 0 auto; }
.breed-review-option-actions .btn-premium,
.breed-review-dismiss .btn-premium {
    width: auto;
    padding: 0.5rem 0.875rem;
    font-size: .78rem;
}

/* A third weight below secondary: bordered but not filled, for the answers that
   should be available without inviting a click. */
.btn-premium-ghost {
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
}
.btn-premium-ghost:hover {
    background: rgba(var(--bg-overlay-rgb), .6);
    color: var(--text-primary);
}

@media (max-width: 520px) {
    /* The name and its answers stop competing for one line. */
    .breed-review-option { flex-direction: column; align-items: stretch; }
    .breed-review-option-actions { justify-content: flex-start; }
}

/* "None of the above, and I know what it should be." Last in the block because
   it is the least common answer, and present in every block because a shortlist
   being wrong about the variety is not rare. */
.breed-review-own {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 10px 0 0;
}
.breed-review-own input[type="text"] {
    flex: 1 1 200px;
    min-width: 0;
    padding: 0.5rem 0.75rem;
    font-size: .85rem;
}
.breed-review-own .btn-premium {
    width: auto;
    flex: 0 0 auto;
    padding: 0.5rem 0.875rem;
    font-size: .78rem;
}

/* --- Feedback: the public form and the operator's inbox ------------------- */

.info-card + .info-card { margin-top: 16px; }
/* The contacts card after the menu keeps the same distance (Dimas, 2026-10-30). */
.settings-menu + .info-card { margin-top: 16px; }
.info-card p { color: var(--text-secondary); font-size: .88rem; line-height: 1.6; margin: 0 0 10px; }
.info-card .info-lede { color: var(--text-primary); }
.info-card .info-note { color: var(--text-muted); font-size: .8rem; }
.info-card .section-header { margin-top: 0; }
.info-roadmap { color: var(--text-secondary); font-size: .88rem; line-height: 1.6; margin: 0 0 12px; padding-left: 1.25rem; }
.info-roadmap li { margin-bottom: 6px; }

/* The welcome card at the foot of the shows list stands apart from the "Show
   next" button above it. Inside the dialog the rule below sets it back to 0. */
.shows-intro-card { margin-top: 16px; }

/* The welcome card, while it is standing inside the dialog. The dialog already
   provides the surface, the border and the padding, so the card drops all
   three, and its own heading gives way to the dialog's title rather than
   printing the same words twice. In the page it is an ordinary card again —
   none of this applies there, which is the point of moving the node instead of
   restyling it. */
.modal-body .shows-intro-card {
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0;
    margin: 0;
}
.modal-body .shows-intro-card .section-header { display: none; }
.shows-intro-dismiss { width: 100%; margin-top: 4px; }
.feedback-field { margin-bottom: 14px; }
.feedback-card .page-action-bar { margin-top: 4px; }
.feedback-reply-to { color: var(--text-muted); font-size: .82rem; margin: 0 0 14px; }
/* The honeypot. Off the page rather than display:none, because a bot that
   checks for a hidden field skips a hidden one and fills this. */
.feedback-company { height: 0; left: -9999px; overflow: hidden; position: absolute; width: 0; }

/* The filters in one row; sideways scroll, no scrollbar, when they do not fit (Dimas, 2026-10-31). */
.feedback-filters { flex-direction: row; flex-wrap: nowrap; margin-bottom: 14px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.feedback-filters::-webkit-scrollbar { display: none; }
.feedback-filters .list-pill { flex: 0 0 auto; white-space: nowrap; }

.feedback-entry {
    border: 1px solid var(--border-color);
    border-radius: 10px;
    margin-bottom: 12px;
    padding: 0.75rem 0.875rem;
}
/* A closed entry recedes; a new one carries the accent edge. */
.feedback-entry-new { border-left: 3px solid var(--accent-primary); }
.feedback-entry-done { opacity: .55; }
.feedback-entry-head {
    align-items: baseline;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 8px;
}
.feedback-kind-tag {
    background: rgba(var(--accent-primary-rgb), .12);
    border-radius: 6px;
    color: var(--accent-text);
    font: 700 .68rem var(--font-display);
    letter-spacing: .04em;
    padding: 0.125rem 0.5rem;
    text-transform: uppercase;
}
.feedback-entry-meta { color: var(--text-muted); font-size: .75rem; }
.feedback-entry-message { font-size: .88rem; margin: 0 0 8px; white-space: pre-line; }
.feedback-entry-contact { color: var(--text-secondary); font-size: .78rem; margin: 0 0 8px; }

/* --- Usage: daily chart, the hours of a day, and the tables --------------------------------- */

.usage-table { border-collapse: collapse; font-size: .82rem; width: 100%; }
.usage-table th {
    color: var(--text-muted);
    font: 700 .68rem var(--font-display);
    letter-spacing: .05em;
    padding: 0.375rem 0.5rem;
    text-align: left;
    text-transform: uppercase;
}
.usage-table td { border-top: 1px solid var(--border-color); padding: 0.375rem 0.5rem; }
.usage-table a { color: var(--accent-text); text-decoration: none; }

/* Page speed cells, coloured by Google's thresholds (SHOW-11). Translucent so
   the same three read on the light and the dark card. */
.usage-vital-good { background: rgba(34, 197, 94, .22); }
.usage-vital-ok { background: rgba(245, 158, 11, .26); }
.usage-vital-poor { background: rgba(239, 68, 68, .28); }
.usage-error-message { max-width: 22rem; overflow-wrap: anywhere; }
.usage-period-line { margin: 0 0 0.5rem; font-weight: 600; color: var(--text-primary, inherit); }


/* Visitors per day: one stacked column per day, surest at the bottom. One hue
   for people (solid when confirmed, faded when probable) and gray for traffic
   nobody vouched for, so the eye reads the orange and discounts the rest. */
/* The period buttons share one row, and the arrows under them page the chart
   by the period's own length (Dimas, 2026-10-21). */
.usage-periods { flex-direction: row; margin-bottom: 0.75rem; }
.usage-periods .list-pill { flex: 1 1 0; justify-content: center; padding: 0.6rem 0.25rem; white-space: nowrap; }
/* Settings → Profiler: both filter groups on one line, each pill as wide as
   its word; they wrap on a narrow screen (Dimas, 2026-10-27, SHOW-48). */
.profiler-filters { align-items: center; display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; margin-bottom: 0.75rem; }
.profiler-filter { align-items: center; flex-direction: row; flex-wrap: wrap; gap: 0.375rem; margin: 0; }
.profiler-filter .list-pill { flex: 0 0 auto; padding: 0.4rem 0.75rem; white-space: nowrap; }
.usage-pager { align-items: center; display: flex; gap: 0.5rem; justify-content: space-between; }
.usage-pager-range { color: var(--text-secondary); font-size: .8rem; text-align: center; }
.usage-pager-arrow {
    align-items: center;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    display: inline-flex;
    font-size: 1.25rem;
    height: 2.25rem;
    justify-content: center;
    line-height: 1;
    text-decoration: none;
    width: 2.75rem;
}
.usage-pager-arrow:hover, .usage-pager-today:hover { border-color: var(--accent-primary); }
.usage-pager-arrow.is-disabled, .usage-pager-today.is-disabled { opacity: .3; }
.usage-pager-end { display: inline-flex; gap: 0.375rem; }
.usage-pager-today {
    align-items: center;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    display: inline-flex;
    font-family: var(--font-display);
    font-size: .8rem;
    font-weight: 600;
    height: 2.25rem;
    padding: 0 0.75rem;
    text-decoration: none;
    white-space: nowrap;
}
.usage-chart { display: grid; gap: 0.5rem; grid-template-columns: auto 1fr; margin-top: 14px; }
.usage-chart-axis {
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    font-size: .68rem;
    height: 180px;
    justify-content: space-between;
    line-height: 1;
    text-align: right;
}
/* Each tick's text centred on its line: the top one half above, the zero half below. */
.usage-chart-axis span:first-child { transform: translateY(-50%); }
.usage-chart-axis span:last-child { transform: translateY(50%); }
.usage-chart-plot {
    background: linear-gradient(var(--border-color), var(--border-color)) 0 50% / 100% 1px no-repeat;
    border-bottom: 1px solid var(--border-color);
    border-top: 1px dashed var(--border-color);
    display: flex;
    gap: 0.125rem;
    height: 180px;
    min-width: 0;
}
.usage-chart-day { display: flex; flex: 1 1 0; flex-direction: column; min-width: 0; position: relative; text-decoration: none; }
.usage-chart-stack { display: flex; flex: 1; flex-direction: column; gap: 0.125rem; justify-content: flex-end; }
/* A show day: a faint band behind the column, neutral so it never reads as a series. */
/* A show is a pale blue band behind its days, its name up the left of the
   first one (Dimas, 2026-10-21; the dashed lines at its ends were dropped the
   same day -- band and name are enough). The shadow carries the band half a
   gap to each side, so consecutive show days read as one block. */
.usage-chart, .usage-chart-legend {
    --usage-show-line: #3B82F6;
    --usage-show-band: color-mix(in srgb, var(--usage-show-line) 12%, transparent);
}
.usage-chart-show .usage-chart-stack {
    background: var(--usage-show-band);
    box-shadow: 0.0625rem 0 0 var(--usage-show-band), -0.0625rem 0 0 var(--usage-show-band);
}
/* The show's name, small, written up just outside the band's first day. */
.usage-chart-show-name {
    color: var(--usage-show-line);
    font-size: .6rem;
    line-height: 1;
    max-height: calc(100% - 4px);
    overflow: hidden;
    pointer-events: none;
    position: absolute;
    right: calc(100% + 0.0625rem + 3px);
    text-overflow: ellipsis;
    top: 4px; /* clear of the plot's top line */
    transform: rotate(180deg);
    white-space: nowrap;
    writing-mode: vertical-rl;
}
.usage-chart-show-name.is-inside { left: 3px; right: auto; }
.usage-chart-show-swatch { background: color-mix(in srgb, var(--usage-show-line) 35%, transparent); }
.usage-chart-day:hover .usage-chart-stack, .usage-chart-day:focus-visible .usage-chart-stack { background: color-mix(in srgb, var(--text-muted) 12%, transparent); }
.usage-chart-day.active .usage-chart-date { color: var(--text-primary); font-weight: 700; }
/* A stretch of days is picked by dragging across the plot (DIM-832). */
[data-range-select] { touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.usage-chart-day.in-range .usage-chart-stack, .usage-chart-day.is-selecting .usage-chart-stack { background: color-mix(in srgb, var(--accent-primary) 14%, transparent); }
[data-range-select].is-dragging .usage-chart-day:not(.is-selecting) .usage-chart-stack { background: none; }
[data-range-select].is-dragging .usage-chart-tip { display: none; }
.usage-chart-seg { display: block; min-height: 2px; }
.usage-chart-stack > .usage-chart-seg:first-child,
.usage-chart-value + .usage-chart-seg { border-radius: 4px 4px 0 0; }
.usage-chart-confirmed { background: var(--accent-primary); }
.usage-chart-probable { background: color-mix(in srgb, var(--accent-primary) 45%, var(--bg-card)); }
.usage-chart-unverified { background: color-mix(in srgb, var(--text-muted) 40%, var(--bg-card)); }
/* New accounts: a narrow bar over the column's foot, in a colour of its own
   (Dimas, 2026-10-21). They are people already in the stack, so it overlays
   rather than adds. */
.usage-chart, .usage-chart-legend, .usage-table { --usage-new-accounts: #22C55E; --usage-total-accounts: #A78BFA; }
.usage-new-dot { display: inline-block; width: 0.5rem; height: 0.5rem; margin-left: 0.25rem; border-radius: 50%; background: var(--usage-new-accounts); vertical-align: middle; }
.usage-chart-new { background: var(--usage-new-accounts); }
.usage-chart-stack > .usage-chart-new {
    border-radius: 2px 2px 0 0;
    bottom: 0;
    left: 30%;
    min-height: 3px;
    pointer-events: none;
    position: absolute;
    width: 40%;
}
.usage-chart-stack { position: relative; }
/* The total of registered accounts (Dimas, 2026-10-23): a line with a dot a
   day over the plot, read on a scale of its own at the right. Under the
   tooltips (z-index 5), and never in the way of the pointer. */
.usage-chart.usage-chart-has-total { grid-template-columns: auto 1fr auto; }
.usage-chart-axis-right { color: var(--usage-total-accounts); text-align: left; }
.usage-chart-plot { position: relative; }
svg.usage-chart-total { height: 100%; inset: 0; overflow: visible; pointer-events: none; position: absolute; width: 100%; z-index: 1; }
.usage-chart-total-line { stroke: var(--usage-total-accounts); stroke-linejoin: round; stroke-width: 2; }
.usage-chart-total-dots { stroke: var(--usage-total-accounts); stroke-width: 7; }
.usage-chart-total-dense .usage-chart-total-dots { stroke-width: 4; }
i.usage-chart-total-accounts { background: var(--usage-total-accounts); border-radius: 50%; }
.usage-chart-line-swatch { background: linear-gradient(var(--usage-total-accounts), var(--usage-total-accounts)) 0 50% / 100% 2px no-repeat; position: relative; width: 16px; }
.usage-chart-line-swatch::after { background: var(--usage-total-accounts); border-radius: 50%; content: ''; height: 6px; left: 5px; position: absolute; top: 2px; width: 6px; }

/* The total of registered accounts (Dimas, 2026-10-23): a line with a dot a
   day over the plot, read on a scale of its own at the right. Under the
   tooltips (z-index 5), and never in the way of the pointer. */
.usage-chart.usage-chart-has-total { grid-template-columns: auto 1fr auto; }
.usage-chart-axis-right { color: var(--usage-total-accounts); text-align: left; }
.usage-chart-plot { position: relative; }
svg.usage-chart-total { height: 100%; inset: 0; overflow: visible; pointer-events: none; position: absolute; width: 100%; z-index: 1; }
.usage-chart-total-line { stroke: var(--usage-total-accounts); stroke-linejoin: round; stroke-width: 2; }
.usage-chart-total-dots { stroke: var(--usage-total-accounts); stroke-width: 7; }
.usage-chart-total-dense .usage-chart-total-dots { stroke-width: 4; }
i.usage-chart-total-accounts { background: var(--usage-total-accounts); border-radius: 50%; }
.usage-chart-line-swatch { background: linear-gradient(var(--usage-total-accounts), var(--usage-total-accounts)) 0 50% / 100% 2px no-repeat; position: relative; width: 16px; }
.usage-chart-line-swatch::after { background: var(--usage-total-accounts); border-radius: 50%; content: ''; height: 6px; left: 5px; position: absolute; top: 2px; width: 6px; }

/* The column's tooltip: its date, its shows, then its numbers, over the
   chart. Columns near either edge open it inwards. */
.usage-chart-tip {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    bottom: calc(100% + 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
    display: none;

    flex-direction: column;
    gap: 0.25rem;
    left: 50%;
    min-width: 12rem;
    padding: 0.625rem 0.75rem;
    pointer-events: none;
    position: absolute;
    transform: translateX(-50%);
    z-index: 5;
}
.usage-chart-tip.is-start { left: 0; transform: none; }
.usage-chart-tip.is-end { left: auto; right: 0; transform: none; }
.usage-chart-day:hover .usage-chart-tip, .usage-chart-day:focus-visible .usage-chart-tip { display: flex; }
.usage-chart-tip-date { color: var(--text-primary); font-size: .78rem; font-weight: 700; margin-bottom: 0.125rem; white-space: nowrap; }
.usage-chart-tip-show { color: var(--usage-show-line); font-size: .72rem; white-space: nowrap; }
.usage-chart-tip-row { align-items: center; color: var(--text-secondary); display: grid; font-size: .74rem; gap: 0.5rem; grid-template-columns: 10px 1fr auto; white-space: nowrap; }
.usage-chart-tip-row b { color: var(--text-primary); font-variant-numeric: tabular-nums; font-weight: 600; }
.usage-chart-tip-row.is-plain { color: var(--text-muted); }
.usage-chart-tip-row:not(.is-plain) + .usage-chart-tip-row.is-plain { border-top: 1px solid var(--border-color); margin-top: 0.125rem; padding-top: 0.375rem; }
.usage-chart-value { color: var(--text-secondary); font-size: .66rem; text-align: center; }
.usage-chart-dense .usage-chart-value { display: none; }
/* A month of numbers does not fit across a phone; the bars still do. */
@media (max-width: 600px) { .usage-chart-mid .usage-chart-value { display: none; } }
/* The dates sit under the baseline, out of the plot's height. */
.usage-chart-date {
    color: var(--text-muted);
    font-size: .64rem;
    left: 50%;
    position: absolute;
    top: calc(100% + 4px);
    transform: translateX(-50%);
    white-space: nowrap;
}
.usage-chart-legend { color: var(--text-secondary); display: flex; flex-wrap: wrap; font-size: .74rem; gap: 0.375rem 1rem; margin: 28px 0 10px; }
.usage-chart-legend span { align-items: center; display: inline-flex; gap: 0.375rem; }
.usage-chart-swatch { border-radius: 2px; display: inline-block; height: 10px; width: 10px; }
.usage-chart-hours { margin-bottom: 26px; }
.usage-chart-hours .usage-chart-axis, .usage-chart-hours .usage-chart-plot { height: 90px; }

/* --- Who was here, on a day of the usage page ------------------------------- */

.usage-subheading { margin: 22px 0 10px; }
/* The address under the name: the display name is what an operator recognises,
   the address is what tells two Marias apart. */
.usage-person-email { color: var(--text-muted); display: block; font-size: .72rem; font-weight: 400; }
.usage-person-window { color: var(--text-muted); white-space: nowrap; }
/* The tail is a summary, not a person, and reads as one. */
.usage-person-rest td { color: var(--text-muted); font-style: italic; }

/* --- Corrections journal --------------------------------------------------- */

/* Wide table, narrow phone: the table scrolls inside its card, the page never. */
.usage-table-scroll { overflow-x: auto; }
/* By type, then by source: two tables, kept apart. */
.usage-sources-kinds { margin-bottom: 1.5rem; }
.correction-action { font-weight: 600; }
.corrections-filters { margin-bottom: 14px; }

/* --- Offline banner -------------------------------------------------------- */

/* Sits on the bottom navigation's shoulder, not over the header: the header
   carries the brand, the clock and the account, and a banner across it hid all
   three. app.js sets the exact bottom offset from the navigation's own height,
   so the two never overlap whatever the safe-area inset adds. */
.offline-banner {
    background: var(--color-important, #F59E0B);
    bottom: 0;
    color: #1a1a1a;
    font: 700 .78rem var(--font-display);
    left: 0;
    letter-spacing: .03em;
    padding: 0.4375rem 0.875rem;
    position: fixed;
    right: 0;
    text-align: center;
    z-index: var(--z-notice);
}

/* --- Country visibility table --------------------------------------------- */

.countries-table-wrap {
    overflow-x: auto;
    margin-top: 1rem;
    margin-bottom: 1.5rem;
}
.countries-table {
    width: 100%;
    border-collapse: collapse;
}
.countries-table th,
.countries-table td {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color, rgba(255, 255, 255, 0.1));
    text-align: left;
}
.countries-table th {
    font-weight: 600;
    color: var(--text-secondary);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.countries-table .cell-center {
    text-align: center;
}
.countries-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 1rem;
}

/* --- Expositions country filter and card header --------------------------- */

.country-filter-form {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: 0.75rem;
}
.country-filter-label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    color: var(--text-secondary);
    font-size: 0.9rem;
}
.country-select {
    padding: 0.35rem 0.75rem;
    font-size: 0.9rem;
    cursor: pointer;
}
.country-single-name {
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--text-primary);
}
.season-source-title {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.season-source-external-link {
    display: inline-flex;
    align-items: center;
    color: var(--text-secondary);
    transition: color 0.15s ease;
}
.season-source-external-link:hover {
    color: var(--accent-text);
}
.season-source-external-link svg {
    width: 1.1rem;
    height: 1.1rem;
}

/* Dashboard ring cards while the quick search is on: a match in a folded part
   of the card has to show, so the folds open (over their inline display:none)
   and the fold toggles step aside. */
.schedule-ring-table.is-searching tr[data-search]:not(.is-filtered-out) { display: table-row !important; }
.schedule-ring-table.is-searching .ring-toggle-row { display: none; }
/* "My dogs only": a row that is not a breed (the "ring complete" line) has
   nothing of yours in it either. */
.schedule-ring-table.is-mine-only tbody tr:not([data-search]) { display: none; }
/* The line above a day's rings, the same on the dashboard and on a show's
   timetable (DIM-779): "Rings ›" at the left, the My dogs switch at the right. */
/* The switch goes to the top line and "Rings" drops under it when the two do not
   share a line: wrap-reverse stacks the lines bottom-up, the source order is
   untouched, and the head's margin-right:auto keeps it left in either layout
   (Dimas, 2026-10-31, SHOW-134). The bar is a size container so the switch can
   shed its stars, then its long labels, by the width it really has (below). */
.breed-filter-bar { --ctl-height: 36px; --tap-height: 32px; --ctl-font: 0.75rem; align-items: center; container-type: inline-size; display: flex; flex-wrap: wrap-reverse; gap: 0.5rem; justify-content: flex-end; margin-bottom: 0.75rem; }
.ring-filter-head { align-items: stretch; display: inline-flex; gap: 0.375rem; margin-right: auto; }
.ring-filter-toggle { align-items: center; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: inline-flex; font: 700 var(--ctl-font) var(--font-display); gap: 0.25rem; min-height: var(--ctl-height); padding: 0 0.5rem; transition: var(--transition-premium); }
.ring-filter-reset { align-items: center; background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: inline-flex; justify-content: center; padding: 0 0.5rem; transition: var(--transition-premium); }
.ring-filter-reset:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.ring-filter-reset-icon { height: 0.9rem; width: 0.9rem; }
.ring-filter-toggle:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.ring-filter-toggle-icon { height: 0.8rem; transition: transform .2s ease; width: 0.8rem; }
.ring-filter-toggle[aria-expanded="true"] .ring-filter-toggle-icon { transform: rotate(90deg); }
.ring-filter-current { color: var(--accent-text); }
.schedule-ring-filter[hidden] { display: none; }
.breed-filter-bar .tracker-filters { margin-bottom: 0; }
.mine-switch { background: var(--bg-surface); border: 1px solid var(--border-color); border-radius: 8px; display: inline-flex; gap: 0.0625rem; padding: 0.0625rem; }
.mine-switch-option { align-items: center; background: none; border: 1px solid transparent; border-radius: 6px; color: var(--text-muted); cursor: pointer; display: inline-flex; font: 700 var(--ctl-font) var(--font-display); min-height: var(--tap-height); padding: 0 0.2rem; transition: var(--transition-premium); }
.mine-switch-option .favorite-star { font-size: 0.8rem; padding: 0 0.05rem 0 0; }
.mine-switch-option:hover { color: var(--text-primary); }
.mine-switch-option.active { background: rgba(var(--accent-primary-rgb), .14); border-color: var(--accent-primary); color: var(--text-primary); }
.mine-switch-option:not(.active) .favorite-star { color: var(--border-color); }
/* Three answers do not fit one line on a phone; they wrap rather than scroll. */
.mine-switch { flex-wrap: wrap; justify-content: flex-end; }
/* Two steps before that wrap, both by the bar's own width, in rem so they follow
   the interface size, and per language because the wording decides what fits
   (SHOW-134). First the stars go; then, when the plain long labels do not fit
   beside "Rings" either, the short ones replace them. Each button keeps its full
   label as its accessible name (aria-label). A container query cannot read its
   content, so the numbers are measured: the bar width each wording needs beside
   "Rings" (the widest over the three interface sizes, which differ by up to
   0.6 rem because glyph widths are rounded) plus a quarter rem. A language not listed (ru today) takes the longest wording's numbers. */
.mine-label-short { display: none; }
@container (max-width: 21.7rem) { .mine-switch:lang(en) .favorite-star { display: none; } }
@container (max-width: 19.95rem) { .mine-switch:lang(en) .mine-label-full { display: none; } .mine-switch:lang(en) .mine-label-short { display: inline; } }
@container (max-width: 26.55rem) { .mine-switch:lang(pt) .favorite-star { display: none; } }
@container (max-width: 24.8rem) { .mine-switch:lang(pt) .mine-label-full { display: none; } .mine-switch:lang(pt) .mine-label-short { display: inline; } }
@container (max-width: 24.65rem) { .mine-switch:lang(es) .favorite-star { display: none; } }
@container (max-width: 22.9rem) { .mine-switch:lang(es) .mine-label-full { display: none; } .mine-switch:lang(es) .mine-label-short { display: inline; } }
@container (max-width: 24.95rem) { .mine-switch:lang(uk) .favorite-star { display: none; } }
@container (max-width: 23.2rem) { .mine-switch:lang(uk) .mine-label-full { display: none; } .mine-switch:lang(uk) .mine-label-short { display: inline; } }
/* The fallback, and Russian, the longest: every language above is excluded from it. */
@container (max-width: 27.35rem) { .mine-switch:not(:lang(en), :lang(pt), :lang(es), :lang(uk)) .favorite-star { display: none; } }
@container (max-width: 25.6rem) { .mine-switch:not(:lang(en), :lang(pt), :lang(es), :lang(uk)) .mine-label-full { display: none; } .mine-switch:not(:lang(en), :lang(pt), :lang(es), :lang(uk)) .mine-label-short { display: inline; } }
/* "My timetable": one list across the rings, start–end, ring, breed, dogs —
   the sheet people copy out by hand. The window needs a wider time column. */
.schedule-own-view { margin-bottom: 1.625rem; }
/* "All rings": My timetable's heading, drawn and stuck like a ring's, so the
   one search magnifier lives on it while the list is shown (DIM-777). */
.schedule-own-head { align-items: center; color: var(--text-primary); display: flex; font: 800 1.05rem var(--font-display); margin: 0; }
.rings-sticky ~ .schedule-own-view > .schedule-own-head { background: var(--bg-base); padding: 0.375rem 6.5rem 0.625rem 0; position: sticky; top: calc(var(--header-height) + var(--rings-sticky-height, 0px)); z-index: calc(var(--z-content) - 1); }
.schedule-own-table th:first-child, .schedule-own-table td:first-child { width: 112px; white-space: nowrap; }
/* Left-aligned, so "A:15" and "8" start at one edge (Dimas, 2026-10-21, DIM-811). */
.schedule-own-table th:nth-child(2), .schedule-own-table td:nth-child(2) { width: 56px; text-align: left; }
.schedule-own-table td.own-ring { color: var(--text-primary); font-weight: 800; }
.schedule-own-table .own-time-end { color: var(--text-muted); }

/* Sign in with Google, under the email form. White with the four-colour mark,
   as Google's own guidelines ask, in both themes. */
.auth-divider { align-items: center; color: var(--text-muted); display: flex; font-size: .8rem; gap: .75rem; margin: 1.125rem 0 0.875rem; }
.auth-divider::before, .auth-divider::after { border-top: 1px solid var(--border-color); content: ""; flex: 1; }
.auth-google { display: grid; gap: 0.5rem; }
.btn-google { align-items: center; background: #fff; border: 1px solid #dadce0; border-radius: var(--radius-sm); color: #1f1f1f; cursor: pointer; display: flex; font: 600 .95rem var(--font-body); gap: .75rem; justify-content: center; min-height: 44px; padding: .625rem 1rem; width: 100%; }
.btn-google:hover { background: #f8f9fa; border-color: #c6c9ce; }
.btn-google:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.btn-google-mark { height: 18px; width: 18px; flex-shrink: 0; }
.auth-google-note { color: var(--text-muted); display: block; font-size: .75rem; line-height: 1.4; }
/* Sign-in (DIM-795): the providers side by side, the reset link beside "Password". */
.auth-providers { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.auth-providers .btn-google { gap: .5rem; padding: .625rem .75rem; }
.auth-card > .auth-google-note { margin-top: .625rem; }
.auth-label-row { align-items: baseline; display: flex; gap: .75rem; justify-content: space-between; }
.auth-forgot { font-size: .8rem; font-weight: 600; }
/* Email first (SHOW-115): the address stays on screen, read-only, once the next part is shown. */
.settings-form input[type="email"][readonly] { opacity: .75; }
.profile-no-password { color: var(--text-muted); display: block; font-size: .8rem; margin-top: 0.25rem; }
.passkey-list { display: grid; gap: .75rem; list-style: none; margin: 0 0 1rem; padding: 0; }
.passkey-item { align-items: center; display: flex; gap: .75rem; justify-content: space-between; }
.passkey-info { display: grid; flex: 1 1 auto; gap: .125rem; min-width: 0; }
.passkey-item .btn-premium { flex: 0 0 auto; padding: .5rem 1rem; width: auto; }
/* On a wide screen a full-width submit reads as a banner; the profile's
   three actions keep a button's width and sit at the right of their card. */
.profile-action { margin-left: auto; max-width: 20rem; }
@media (max-width: 600px) { .profile-action { max-width: none; } }
.passkey-info small { color: var(--text-muted); font-size: .76rem; }
.auth-passkey { margin: .875rem 0 .75rem; }
/* Without a passkey the providers are first under the heading and need the
   passkey's gap; under a visible passkey they keep its bottom margin only (SHOW-114). */
.auth-card .auth-providers { margin-top: .875rem; }
.auth-check-email-back { display: block; margin-top: 1.25rem; text-align: center; text-decoration: none; }
.auth-passkey:not([hidden]) + .auth-providers { margin-top: 0; }
.btn-passkey { align-items: center; background: transparent; border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); cursor: pointer; display: flex; font: 600 1rem var(--font-body); gap: .625rem; justify-content: center; min-height: 48px; padding: .625rem 1rem; width: 100%; }
.btn-passkey:hover { background: rgba(255, 255, 255, .04); border-color: var(--text-muted); }
.btn-passkey:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.btn-passkey:disabled { cursor: progress; opacity: .6; }
.btn-passkey-mark { flex-shrink: 0; height: 1.375rem; width: 1.375rem; }
/* Dashboard suggestion to add a passkey (SHOW-69): hidden until the script finds a platform authenticator. */
.passkey-nudge { margin: 1rem 0; padding: 1rem 1.25rem; }
.passkey-nudge[hidden] { display: none; }
.passkey-nudge-title { align-items: center; display: flex; font-size: 1rem; gap: .5rem; margin: 0 0 .5rem; }
.passkey-nudge-icon { color: var(--accent-text); flex-shrink: 0; height: 1.25rem; width: 1.25rem; }
.passkey-nudge p { color: var(--text-secondary); font-size: .85rem; line-height: 1.5; margin: 0 0 .75rem; }
.passkey-nudge-actions { display: flex; gap: .5rem; justify-content: flex-end; margin-left: auto; max-width: 20rem; }
.passkey-nudge-actions .btn-premium { flex: 1 1 0; }
@media (max-width: 600px) { .passkey-nudge-actions { max-width: none; } }
.passkey-need { display: grid; gap: .5rem; margin-top: 1rem; max-width: 22rem; }
.passkey-need p { color: var(--text-secondary); margin: 0; }
.passkey-empty, .passkey-unsupported { color: var(--text-muted); margin: 0 0 1rem; }
.btn-link { background: none; border: 0; color: var(--text-secondary); cursor: pointer; font: inherit; padding: 0; text-decoration: underline; }
.btn-link:hover { color: var(--accent-text); }
.profile-google-link { margin-top: -0.25rem; }
.profile-google-status { align-items: baseline; display: flex; flex-wrap: wrap; font-size: .85rem; gap: 0.25rem 0.75rem; margin-top: -0.25rem; }
.profile-google-status > span { color: var(--color-friends); }
.profile-google-status small { color: var(--text-muted); flex-basis: 100%; }
/* Unlink is a grey button like Update avatar, as wide as its word. */
.settings-form .profile-unlink { font-size: .78rem; margin-top: 0; padding: 0.5rem 0.875rem; width: auto; }
/* The address cannot be changed here, so it must not look like a field that
   can: no input background, a dashed edge, no focus ring (Dimas, 2026-10-30, SHOW-90). */
.settings-form input.profile-email-readonly, .settings-form input.profile-email-readonly:focus { background: transparent; border-color: var(--border-color); border-style: dashed; color: var(--text-secondary); cursor: default; }

/* Ring assistant mode (DIM-638) --------------------------------------------- */
.user-role-assistant { background: rgba(var(--accent-primary-rgb),.12); color: var(--accent-text); margin-top: 0.25rem; text-transform: none; }
.assistant-permanent { align-items: flex-start; display: flex; gap: 0.5rem; }
/* .settings-form input is display:block;width:100%, which stretched the
   checkbox across half the row and pushed its label to the far side. */
.settings-form .assistant-permanent input { flex: 0 0 auto; margin: 0.25rem 0 0; width: auto; }
.settings-form .assistant-permanent span { flex: 1 1 auto; }
/* "Permanently" leaves the show choice nothing to decide; it has to look it. */
.settings-form select:disabled { cursor: not-allowed; opacity: .45; }
.assistant-permanent small { color: var(--text-muted); display: block; font-weight: 400; }
/* User, Steward, Steward Catalog: the name, and under it one line of what it does. */
.settings-assistant-modes.import-tabs { margin-bottom: 0; }
.settings-assistant-modes .import-tab { align-items: center; display: flex; flex-direction: column; gap: 0.125rem; line-height: 1.2; padding-bottom: 0.5rem; padding-top: 0.5rem; }
.settings-assistant-mode-name { font-size: 1rem; font-weight: 800; }
.settings-assistant-mode-hint { color: var(--text-muted); font-size: .7rem; font-weight: 500; white-space: normal; }
/* On the filled button the grey hint read badly: it takes the button's own text colour (Dimas, 2026-10-31). */
.settings-assistant-modes .import-tab.active .settings-assistant-mode-hint { color: currentColor; }
.steward-tip { margin-top: 1rem; }
.assistant-all-shows { margin: 0 0 0.75rem; text-align: right; }
.assistant-all-shows a { font-weight: 600; }
.assistant-sheet { margin-top: 1rem; }
.assistant-sheet-summary { color: var(--text-muted); font-size: .8rem; margin: -0.25rem 0 0.5rem; }
.assistant-sheet-summary strong { color: var(--text-primary); }
.assistant-sheet-summary .assistant-add-dog { display: none; background: none; border: 1px solid var(--border-input); border-radius: 6px; color: var(--accent-text); cursor: pointer; font: 600 .8rem var(--font-body); margin-left: 0.5rem; min-height: 1.75rem; padding: 0 0.5rem; }
/* Shown only while the order is edited. */
.is-ordering .assistant-sheet-summary .assistant-add-dog { display: inline-block; }
/* A breed whose catalogue count differs from the timetable's (SHOW-52). */
.assistant-classes .assistant-mismatch { margin-bottom: 0.5rem; }
.assistant-mismatch { align-items: center; background: rgba(var(--color-important-rgb), 0.12); border: 1px solid rgba(var(--color-important-rgb), 0.4); border-radius: 0.625rem; color: var(--text-primary); display: flex; flex-wrap: wrap; font-size: .85rem; gap: 0.5rem 0.75rem; justify-content: space-between; padding: 0.5rem 0.75rem; }
/* Text left, buttons right on one line; the buttons wrap under the text when it would drop below 12rem. */
.assistant-mismatch-text { flex: 1 1 12rem; min-width: 0; }
.assistant-mismatch-question { display: block; font-weight: 700; margin-top: 0.125rem; }
/* Both buttons on one line, compact, even at 360 px. */
.assistant-mismatch-actions { display: grid; gap: 0.5rem; grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 100%; }
/* app.js sets .is-stacked when the buttons sit under the text: both centred. */
.assistant-mismatch.is-stacked { justify-content: center; }
.assistant-mismatch.is-stacked .assistant-mismatch-text { text-align: center; }
.assistant-mismatch.is-stacked .assistant-mismatch-actions { justify-content: center; }
/* Two equal answers, each a name over a short line of what it does (SHOW-52). Equal columns; where they are too narrow the words wrap inside the button, never past its edge. */
.assistant-mismatch-choice { align-items: center; display: inline-flex; flex-direction: column; gap: 0.125rem; justify-content: center; line-height: 1.15; min-width: 0; overflow-wrap: anywhere; padding: 0.4375rem 0.75rem; text-align: center; }
.assistant-mismatch-choice-title { font-size: .75rem; font-weight: 700; }
.assistant-mismatch-choice-hint { font-size: .65rem; font-weight: 500; letter-spacing: normal; opacity: .85; text-transform: none; }
/* Pushed to the right edge of the breed cell; the cell stays one tap target. */
.assistant-mismatch-tag { background: var(--color-important); border-radius: 0.25rem; color: #1f1300; float: right; font: 700 .65rem var(--font-body); margin-left: 0.5rem; padding: 0.125rem 0.375rem; }
/* Breeds the catalogue lists and the timetable lacks (SHOW-52): a banner above the timetable in Edit mode only, a tag on the summary line otherwise. */
.assistant-orphans { display: none; margin: 0 0 0.75rem; }
.is-ordering .assistant-orphans { display: block; }
.assistant-orphans-title { display: block; font-size: .85rem; margin-bottom: 0.375rem; }
.assistant-orphans .assistant-mismatch + .assistant-mismatch { margin-top: 0.5rem; }
.assistant-orphans .assistant-mismatch-actions { grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); }
.assistant-sheet-summary .assistant-orphan-tag { float: none; margin-left: 0.25rem; }
.is-ordering .assistant-sheet-summary .assistant-orphan-tag { display: none; }
/* A row the steward placed carries a quiet tag, and its Undo is there only while the order is edited. */
.assistant-added-tag { background: rgba(var(--text-secondary-rgb), 0.18); border-radius: 0.25rem; color: var(--text-primary); float: right; font: 700 .65rem var(--font-body); margin-left: 0.5rem; padding: 0.125rem 0.375rem; }
.assistant-unplace { display: none; margin-left: 0.5rem; }
.is-ordering .assistant-unplace { display: inline-flex; }
/* A settled decision reads as settled, not as a warning; its one button is a single line (SHOW-52). */
.assistant-mismatch.is-resolved { background: rgba(var(--text-secondary-rgb), 0.08); border-color: var(--border-input); }
.assistant-mismatch.is-resolved .assistant-mismatch-actions { grid-template-columns: auto; }
/* The timetable's count struck through before the catalogue's. */
.assistant-count-was { color: var(--text-secondary); margin-right: 0.25rem; }
/* Undo is a calm way back, not an answer to a question: grey, same size (SHOW-52). */
.assistant-mismatch-choice.is-quiet { background-color: transparent; border: 1px solid var(--text-secondary); box-shadow: none; color: var(--text-secondary); }
.assistant-mismatch-choice.is-quiet:hover { background-color: rgba(var(--text-secondary-rgb), 0.12); border-color: var(--text-primary); box-shadow: none; color: var(--text-primary); }
/* A number added at the ring carries a warning mark after it (SHOW-52). */
.assistant-added-mark { font-size: .7em; margin-left: 0.2em; }
.assistant-dog-number-row { align-items: center; display: flex; gap: 0.5rem; }
.assistant-dog-number-row input { flex: 1 1 auto; }
.assistant-dog-number-row input[readonly] { opacity: .8; }
.assistant-dog-number-edit { align-items: center; background: none; border: 1px solid var(--border-input); border-radius: 6px; color: var(--text-secondary); cursor: pointer; display: inline-flex; flex: 0 0 auto; justify-content: center; min-height: 2.75rem; min-width: 2.75rem; padding: 0; }
.assistant-dog-number-edit .action-icon { height: 1.125rem; width: 1.125rem; }
.assistant-dog-dialog { max-width: 26rem; }
.assistant-dog-field { margin: 0.5rem 0 0.75rem; }
.assistant-dog-field select, .assistant-dog-field input { font-weight: 600; min-height: 2.75rem; padding: 0 0.5rem; width: 100%; }
.assistant-dog-choices { display: grid; gap: 0.375rem; grid-template-columns: repeat(4, 1fr); }
.assistant-dog-choices[data-dog-row="sex"] { grid-template-columns: repeat(2, 1fr); }
.assistant-dog-choices .assistant-result-choice { font-size: .8rem; }
.assistant-dog-error { color: var(--color-my-dogs); font-size: .85rem; margin-top: 0.5rem; }
.assistant-sheet-practice { box-sizing: border-box; margin: -0.5rem auto 1rem; max-width: 800px; padding: 0.625rem 0.75rem; border: 1px solid rgba(var(--color-important-rgb), 0.4); border-radius: 0.625rem; background: rgba(var(--color-important-rgb), 0.12); color: var(--text-primary); font-size: .85rem; line-height: 1.4; }
/* With the button column the heading "Dogs" spans it too, so a fixed layout
   cannot read the column widths off the heading row: the colgroup carries them. */
.assistant-table.has-start col.assistant-col-time { width: 5.25rem; }
.assistant-table.has-start col.assistant-col-dogs { width: 3.25rem; }
.assistant-table.has-start col.assistant-col-action { width: 5.25rem; }
.assistant-table.has-start th:last-child { width: auto; white-space: nowrap; }
.assistant-table td { padding-bottom: 0.375rem; padding-top: 0.375rem; }
.assistant-start-cell { text-align: right; }
.assistant-start { font-size: .8rem; min-height: 0; padding: 0.375rem 0.75rem; width: auto; }
.assistant-start.assistant-started { white-space: normal; line-height: 1.2; max-width: 9rem; }
.ring-toggle-btn { background: transparent; border: none; box-shadow: none; color: var(--text-secondary); font-size: 0.75rem; min-height: 0; padding: 0.25rem 0.75rem; }

/* The ring sheet under each breed on the assistant's page (DIM-651): the
   catalogue's classes in judging order, each with its numbers to tick off.
   A tick is green, a no-show is struck through, an unmarked number is plain. */
.assistant-classes-row td { padding: 0 0.75rem 0.625rem; }
.assistant-classes-row > td { padding-top: 0.75rem; }
.assistant-classes { display: grid; gap: 0.375rem; }
.assistant-class { align-items: center; display: grid; gap: 0.5rem; grid-template-columns: minmax(6.5rem, auto) 1fr auto; }
.assistant-class-name { color: var(--text-secondary); font-size: .8rem; font-weight: 600; }
.assistant-class-count { color: var(--text-muted); font-size: .8rem; min-width: 2.5rem; padding: 0 0.75rem; text-align: center; }
.assistant-numbers { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.assistant-number { background: var(--bg-control); border: 1px solid var(--border-input); border-radius: 6px; color: var(--text-primary); cursor: pointer; font: 700 .9rem var(--font-display); min-height: 2.25rem; min-width: 3.25rem; padding: 0.25rem 0.5rem; transition: var(--transition-premium); }
.assistant-number.is-done { background: rgba(var(--color-friends-rgb), .18); border-color: var(--color-friends); }
.assistant-number.is-done::after { content: " ✓"; color: var(--color-friends); }
.assistant-number.is-absent { border-color: var(--color-my-dogs); color: var(--text-muted); text-decoration: line-through; }
.assistant-number.is-absent::after { content: " ✗"; color: var(--color-my-dogs); text-decoration: none; display: inline-block; }
.assistant-number:disabled { cursor: default; opacity: .7; }

/* Class results and comparisons on the ring sheet (DIM-630). A number with a
   result shows it under the number; a comparison is a row like a class, its
   lineup drawn by the server. A number that has to come back to the ring is
   dashed; the winner is filled. */
.assistant-number.has-result { display: inline-flex; flex-direction: column; line-height: 1.1; }
.assistant-number-result { color: var(--text-secondary); font: 600 .7rem var(--font-body); }
.assistant-derived { padding-left: 0.25rem; }
.assistant-derived-award { background: none; border: 1px solid var(--border-input); border-radius: 999px; color: var(--text-secondary); cursor: pointer; font-size: .75rem; padding: 0.125rem 0.625rem; }
.assistant-derived-award.is-withheld { text-decoration: line-through; }
.assistant-comparison { align-items: center; border-left: 3px solid var(--accent-primary, var(--border-input)); display: grid; gap: 0.5rem; grid-template-columns: minmax(6.5rem, auto) 1fr; padding-left: 0.5rem; }
.assistant-comparison.is-waiting { opacity: .6; }
/* A comparison's choices (the numbers and Not awarded) are one choice of one
   answer: framed together as a segmented switch, hugging its buttons
   (Dimas, 2026-11-01, SHOW-127). */
.assistant-comparison .assistant-numbers { background: rgba(var(--accent-primary-rgb), .05); border: 1px solid var(--border-input); border-radius: 12px; justify-self: start; padding: .3rem; }
.assistant-comparison-note { color: var(--text-muted); font-size: .75rem; grid-column: 2; }
.assistant-candidate.is-callback { border-style: dashed; border-width: 2px; }
.assistant-candidate.is-winner { background: rgba(var(--color-friends-rgb), .25); border-color: var(--color-friends); }
.assistant-candidate.is-winner::after { content: " ★"; color: var(--color-friends); }
.assistant-withhold { background: none; border: 1px dashed var(--border-input); border-radius: 6px; color: var(--text-muted); cursor: pointer; font-size: .75rem; min-height: 2.25rem; padding: 0.25rem 0.5rem; }
.assistant-withhold.is-withheld { border-style: solid; border-color: var(--color-my-dogs); color: var(--text-primary); }
.assistant-final { border-top: 1px solid var(--border-input); display: grid; gap: 0.375rem; margin-top: 0.25rem; padding-top: 0.375rem; }
.assistant-final-title { color: var(--text-secondary); font-size: .8rem; font-weight: 700; }
.assistant-result-dialog { max-width: 26rem; }
.assistant-result-label { color: var(--text-secondary); font-size: .8rem; font-weight: 600; margin: 0.5rem 0 0.375rem; }
.assistant-result-choices { display: grid; gap: 0.375rem; grid-template-columns: repeat(5, 1fr); }
.assistant-result-choices[data-result-row="qualification"] { grid-template-columns: repeat(6, 1fr); }
.assistant-result-choice { background: var(--bg-control); border: 1px solid var(--border-input); border-radius: 6px; color: var(--text-primary); cursor: pointer; font: 700 .9rem var(--font-display); min-height: 2.75rem; min-width: 0; padding: 0 0.125rem; }
.assistant-result-choice:disabled { cursor: not-allowed; opacity: .3; }
.assistant-result-choice.is-selected { background: rgba(var(--color-friends-rgb), .25); border-color: var(--color-friends); }
.assistant-result-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: space-between; margin-top: 1rem; }
/* Save and Close side by side above Absent: a light green and a light red (DIM-791). */
.assistant-result-confirm { display: grid; gap: 0.5rem; grid-template-columns: 1fr 1fr; margin-top: 1rem; }
.assistant-result-confirm .btn-premium { width: 100%; }
.assistant-result-confirm .assistant-result-save { background: rgba(var(--color-friends-rgb), .16); border-color: rgba(var(--color-friends-rgb), .45); color: var(--text-primary); }
.assistant-result-confirm .assistant-result-save:disabled { cursor: not-allowed; opacity: .4; }
.assistant-result-confirm .assistant-result-cancel { background: rgba(239, 68, 68, .14); border-color: rgba(239, 68, 68, .4); color: var(--text-primary); }

/* Start and the arrow that opens a breed's numbers sit side by side. The
   arrow points right while the numbers are folded and down while they show. */
.assistant-actions { align-items: center; display: inline-flex; gap: 0.375rem; justify-content: flex-end; }
/* Order: Start gives way to a grab handle while the running order is edited
   (Dimas, 2026-10-26). The button in the heading reads Order, then Save. */
.order-toggle {
    align-items: center;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-secondary);
    cursor: pointer;
    display: inline-flex;
    font: 700 .78rem var(--font-display);
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
}
.order-actions { align-items: center; display: inline-flex; gap: 0.375rem; margin-left: auto; }
/* The steward-mode panel stays one thin row. The title is the point and never
   gives way; only the buttons adapt, in steps the client measures: first Change
   ring says just "Ring" (.is-short), then both buttons show icons instead of
   words (.is-icons). Nothing is cut with an ellipsis (Dimas, 2026-11-01, SHOW-127). */
.steward-offer-banner.steward-mode-banner { flex-wrap: nowrap; }
.steward-mode-banner > span:first-child { flex: none; white-space: nowrap; }
.steward-mode-banner .steward-offer-actions { display: flex; flex: none; flex-wrap: nowrap; gap: .5rem; }
.steward-mode-banner .steward-offer-actions .btn-premium { align-items: center; display: inline-flex; white-space: nowrap; }
.steward-btn-icon, .steward-change-ring-short { display: none; }
.steward-mode-banner.is-short .steward-change-ring-full { display: none; }
.steward-mode-banner.is-short .steward-change-ring-short { display: inline; }
.steward-mode-banner.is-icons .steward-btn-text { display: none; }
.steward-mode-banner.is-icons .steward-btn-icon { display: inline-block; height: 1rem; width: 1rem; }
/* "CCJ → 53": an arrow from the title to the number that holds it (Dimas, 2026-11-01, SHOW-127). */
.assistant-derived-arrow { color: var(--text-muted); font-weight: 400; }
.order-reset {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-secondary);
    cursor: pointer;
    display: none;
    font: 700 .78rem var(--font-display);
    padding: 0.375rem 0.75rem;
}
.is-ordering .order-reset { display: inline-flex; }
.order-reset { align-items: center; gap: 0.375rem; }
.order-cancel {
    align-items: center;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-secondary);
    cursor: pointer;
    display: none;
    font: 700 .78rem var(--font-display);
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
}
.is-ordering .order-cancel { display: inline-flex; }
.order-cancel .action-icon { height: 1rem; width: 1rem; }
.order-reset .action-icon { height: 1rem; width: 1rem; }
.order-toggle .order-icon-save, .order-toggle.is-saving .order-icon-edit { display: none; }
.order-toggle.is-saving .order-icon-save { display: inline-block; }
.order-toggle.is-saving { background: rgba(var(--accent-primary-rgb), .14); border-color: var(--accent-primary); color: var(--text-primary); }
.order-toggle .action-icon { height: 1rem; width: 1rem; }
.order-toggle:disabled { opacity: .5; }
.time-ahead.is-new-time { color: var(--color-friends); text-transform: uppercase; }
.match-newtime { color: var(--color-friends); display: block; font: 700 .64rem/1.3 var(--font-display); text-transform: uppercase; }
.match-item.is-shrunk .match-newtime { display: none; }
.order-moved { display: none; }
/* The saved order's arrow, for everybody (Dimas, 2026-10-27); while ordering,
   the steward's live arrow takes its place. */
.moved-arrow { color: var(--color-friends); display: inline-flex; margin-right: 0.25rem; vertical-align: -0.125rem; }
.moved-arrow .action-icon { height: 0.875rem; width: 0.875rem; }
.is-ordering .moved-arrow { display: none; }
.is-ordering tr.is-moved .order-moved { color: var(--color-friends); display: inline-flex; margin-right: 0.25rem; vertical-align: -0.125rem; }
.order-moved .action-icon { display: none; height: 0.875rem; width: 0.875rem; }
tr.is-moved-down .order-moved .order-moved-down, tr.is-moved-up .order-moved .order-moved-up { display: inline-block; }
.order-newtime { color: var(--color-friends); display: block; font: 700 .64rem/1.3 var(--font-display); text-transform: uppercase; }
.order-handle { display: none; }
.is-ordering .order-handle {
    align-items: center;
    border: 1px solid var(--border-input);
    border-radius: 6px;
    color: var(--text-secondary);
    cursor: grab;
    display: inline-flex;
    justify-content: center;
    min-height: 2rem;
    min-width: 2rem;
    touch-action: none;
    user-select: none;
}
.order-handle .action-icon { height: 1.125rem; width: 1.125rem; pointer-events: none; }
.is-ordering .assistant-start { display: none; }
/* While ordering every breed is shown as it is, the ones already over too:
   greyed rows read as locked (Dimas, 2026-10-27). */
.is-ordering .schedule-table tr.past td { opacity: 1; }
/* Ordering moves breeds, it does not read their numbers: the catalogue arrow
   is not shown while Order is on (Dimas, 2026-10-27). */
.is-ordering .assistant-sheet-toggle { display: none; }

.assistant-sheet-toggle { align-items: center; background: none; border: 1px solid var(--border-input); border-radius: 6px; color: var(--text-secondary); cursor: pointer; display: inline-flex; justify-content: center; min-height: 2rem; min-width: 2rem; padding: 0; }
.assistant-sheet-toggle .assistant-sheet-chevron { height: 1.125rem; transition: transform .2s ease; width: 1.125rem; }
.assistant-sheet-toggle[aria-expanded="false"] .assistant-sheet-chevron { transform: rotate(-90deg); }
.assistant-classes-row.is-collapsed { display: none !important; }
/* With the arrow beside Start the last column is as wide as its two buttons,
   in whatever language Start is written — "Iniciar" is wider than "Старт",
   and a fixed width pushed the arrow out and the table into a sideways
   scroll. The table lays itself out from its content instead; the breed name
   takes what is left and wraps. */
.assistant-table.has-sheet { table-layout: auto; }
.assistant-table.has-sheet th:last-child, .assistant-table.has-sheet td:last-child { white-space: nowrap; width: 1%; }
.assistant-table.has-sheet .schedule-table-breed { overflow-wrap: anywhere; }
.assistant-table.has-sheet .assistant-classes-row td:last-child { white-space: normal; width: auto; }
.assistant-table .schedule-table-breed[data-action="toggle-sheet-row"] { cursor: pointer; }
/* Breed takes the width; time, dogs and the button column stay fixed (Dimas,
   2026-10-27). While ordering, the button column holds only the handle (and the
   numbers arrow), so it is no wider than that. */
.assistant-sheet.is-ordering .assistant-table.has-start:not(.has-sheet) col.assistant-col-action { width: 3rem; }
.assistant-table.has-sheet .schedule-table-breed { width: 100%; }
/* An auto-laid table reads width on a cell as a wish; min-width holds it. */
.assistant-table.has-sheet th:first-child, .assistant-table.has-sheet td.schedule-table-time { box-sizing: border-box; min-width: 5.25rem; width: 5.25rem; }
.assistant-table.has-sheet tr[data-item-id] > td:nth-child(3) { box-sizing: border-box; min-width: 3.25rem; width: 3.25rem; }

/* Hints under the show card on the dashboard (DIM-774). A class of their own,
   not card-premium: they are advice about the app, and must not read as one
   more show or ring card. Side by side where there is room, stacked on a phone;
   the button sits at the bottom right whatever the text length. */
.dashboard-banners {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: 0.625rem;
    margin: 3rem 0 1.5rem;
}
.dashboard-banner {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 0.9rem 1rem 0.9rem 1.15rem;
    border-radius: var(--radius-md);
    border: 1px solid rgba(var(--accent-primary-rgb), .28);
    background: linear-gradient(135deg, rgba(var(--accent-primary-rgb), .14) 0%, rgba(var(--accent-primary-rgb), .03) 60%), var(--bg-surface);
    overflow: hidden;
}
.dashboard-banner::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 0.25rem;
    background: var(--accent-primary);
}
.dashboard-banner-title {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    color: var(--text-primary);
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    line-height: 1.3;
    margin: 0 0 0.6rem;
}
.dashboard-banner-title .favorite-star,
.dashboard-banner-icon { color: var(--accent-text); }
.dashboard-banner-icon { width: 1.125rem; height: 1.125rem; flex-shrink: 0; }
.dashboard-banner p {
    color: var(--text-secondary);
    font-size: .85rem;
    line-height: 1.5;
    margin: 0 0 0.75rem;
    flex: 1;
}
.dashboard-banner-btn { align-self: flex-end; width: auto; padding: 0.55rem 1rem; }
/* Between shows (SHOW-57): one banner under the show card, its buttons in a row. */
.dashboard-between-shows { margin: 1.5rem 0; }
.dashboard-between-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: flex-end; }
/* All shows on the left, lists and time imitation on the right (Dimas, 2026-10-29). */
.dashboard-between-actions .dashboard-between-all { margin-right: auto; }
.dashboard-banner p a { font-weight: 600; }
/* On a narrow screen every button has a row of its own (Dimas, 2026-11-01, SHOW-127). */
@media (max-width: 600px) {
    .dashboard-between-actions .dashboard-between-all { flex-basis: 100%; justify-content: center; margin-right: 0; }
    .dashboard-between-actions .dashboard-banner-btn:not(.dashboard-between-all) { flex: 1 1 100%; justify-content: center; }
}
.dashboard-between-actions .dashboard-banner-btn { align-self: auto; }
/* Add shows to calendar beside All shows, styled as the banner's other buttons
   rather than the compact menu by a section heading (Dimas, 2026-10-31, SHOW-127). */
.dashboard-between-actions-calendar .dashboard-between-all { margin-right: 0; }
.dashboard-between-actions .calendar-subscribe { margin-right: auto; order: 0; }
.dashboard-between-actions .calendar-subscribe-toggle {
    font-family: var(--font-display);
    font-weight: 700;
    height: 100%;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.dashboard-between-actions .calendar-subscribe-menu { left: 0; right: auto; }
/* The banner's overflow: hidden only rounds its stripe, and it cut the open
   menu off at the banner's edge; the stripe is rounded by itself instead. */
.dashboard-between-shows { overflow: visible; }
.dashboard-between-shows::before { border-radius: var(--radius-md) 0 0 var(--radius-md); }
@media (max-width: 600px) {
    .dashboard-between-actions .calendar-subscribe { flex: 1 1 100%; margin-right: 0; }
    .dashboard-between-actions .calendar-subscribe-toggle { justify-content: center; width: 100%; }
}

/* A clock adjustment is a compact practice control, not another dashboard card.
   Solid buttons that say which way they move the clock, and no wider than
   800 px (Dimas, 2026-10-27, SHOW-38): grey ones were not seen. */
.dashboard-imitation-controls { align-items: center; background: rgba(var(--color-important-rgb), .12); border: 1px solid rgba(var(--color-important-rgb), .45); border-radius: 12px; box-sizing: border-box; color: var(--text-primary); display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 auto 1rem; max-width: 800px; padding: .5rem .75rem; width: 100%; }
.dashboard-imitation-controls .imitation-fold { align-items: center; background: transparent; border: 0; color: inherit; cursor: pointer; display: inline-flex; font: 700 .85rem var(--font-display); gap: .35rem; margin-right: auto; padding: 0; white-space: nowrap; }
.dashboard-imitation-controls .imitation-fold .action-icon { height: 1.1rem; width: 1.1rem; }
.dashboard-imitation-controls form { display: contents; }
/* Folded by default: one thin row, a tap on it opens the bar (Dimas, 2026-11-01, SHOW-127). */
.imitation-controls-body { display: contents; }
.dashboard-imitation-controls.is-folded .imitation-controls-body { display: none; }
.dashboard-imitation-controls.is-folded { padding: .3rem .75rem; }
.dashboard-imitation-controls.is-folded .imitation-fold { flex: 1; }
.dashboard-imitation-controls .imitation-fold-chevron { margin-left: auto; transition: transform .15s; }
.dashboard-imitation-controls:not(.is-folded) .imitation-fold-chevron { transform: rotate(180deg); }
.dashboard-imitation-controls .imitation-step,
.dashboard-imitation-controls .imitation-exit { align-items: center; border-radius: 8px; cursor: pointer; display: inline-flex; font: 700 .85rem var(--font-display); gap: .3rem; line-height: 1; min-height: 2.25rem; padding: .45rem .8rem; white-space: nowrap; }
.dashboard-imitation-controls .imitation-step { background: var(--color-important); border: 1px solid var(--color-important); color: #1f1300; text-decoration: none; }
.dashboard-imitation-controls .imitation-step:hover { filter: brightness(1.08); }
.dashboard-imitation-controls .imitation-exit { background: transparent; border: 1.5px solid var(--color-important); color: var(--text-primary); margin-left: .25rem; }
.dashboard-imitation-controls .imitation-exit:hover { background: rgba(var(--color-important-rgb), .18); }
/* Set new time is drawn like Real time: outlined, the steps stay solid (Dimas, 2026-10-30, SHOW-110). */
.dashboard-imitation-controls .imitation-step.imitation-set { background: transparent; border: 1.5px solid var(--color-important); color: var(--text-primary); filter: none; }
.dashboard-imitation-controls .imitation-step.imitation-set:hover { background: rgba(var(--color-important-rgb), .18); }
.dashboard-imitation-controls .imitation-step:disabled,
.dashboard-imitation-controls .imitation-exit:disabled { cursor: progress; opacity: .6; }
.dashboard-imitation-controls .action-icon { height: 1.05rem; width: 1.05rem; }
/* Amber on white is too faint for words; the light theme darkens it. */
:root[data-theme="light"] .dashboard-imitation-controls .imitation-fold,
:root[data-theme="light"] .dashboard-imitation-controls .imitation-exit,
:root[data-theme="light"] .dashboard-imitation-controls .imitation-step.imitation-set { border-color: #B45309; color: #B45309; }
@media (prefers-color-scheme: light) {
    :root[data-theme="system"] .dashboard-imitation-controls .imitation-fold,
    :root[data-theme="system"] .dashboard-imitation-controls .imitation-exit,
    :root[data-theme="system"] .dashboard-imitation-controls .imitation-step.imitation-set { border-color: #B45309; color: #B45309; }
}
@media (max-width: 480px) {
    .dashboard-imitation-controls .imitation-fold { flex-basis: 100%; }
    .dashboard-imitation-controls .imitation-step,
    .dashboard-imitation-controls .imitation-exit { flex: 1 1 auto; justify-content: center; }
    .dashboard-imitation-controls .imitation-exit { margin-left: 0; }
}

/* The row standing in for a breed while the Lists page saves it (DIM-776). */
.list-item-pending .breed-item-name,
.list-item-failed .breed-item-name { font-family: var(--font-display); font-weight: 600; }
.list-item-pending .breed-item-meta,
.list-item-failed .breed-item-meta { display: flex; flex-direction: column; gap: 0.25rem; }
.list-item-status {
    align-items: center;
    color: var(--text-muted);
    display: inline-flex;
    font-size: .8rem;
    gap: 0.5rem;
}
.list-item-failed .list-item-status { color: var(--color-my-dogs); }
.list-item-spinner {
    animation: list-item-spin .8s linear infinite;
    border: 2px solid rgba(var(--accent-primary-rgb), .25);
    border-radius: 50%;
    border-top-color: var(--accent-primary);
    display: inline-block;
    height: 0.875rem;
    width: 0.875rem;
}
@keyframes list-item-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .list-item-spinner { animation-duration: 2.4s; } }

/* Create a list, and change the open one, on the line under the kinds (DIM-775).
   On a phone the two share the line rather than stacking into a wall. */
.list-type-actions { justify-content: flex-end; margin-top: 0; }
@media (max-width: 560px) {
    .list-type-actions .btn-premium,
    .list-type-actions .bulk-actions { flex: 0 1 auto; min-width: 0; }
    .list-type-actions .btn-premium { font-size: .74rem; letter-spacing: .03em; padding: 0.7rem 0.5rem; }
    .list-type-actions .bulk-actions-trigger { width: 100%; }
}
.list-items-actions { margin: 0 0 0.75rem; }

/* A show list's pin, in the list's colour, where other lists have a dot (DIM-775). */
.list-pill-pin { display: inline-flex; flex: 0 0 auto; }
.list-pill-pin-icon { height: 1rem; stroke-width: 2; width: 1rem; }


/* The open list's heading carries its Change menu at the right, after the rule
   (DIM-775). The menu is a chip, and its panel must not inherit the heading's
   capitals and letter spacing. */
.list-items-heading .bulk-actions { order: 1; }
/* Share beside Change, after the rule (DIM-792). */
.list-items-heading .list-share-chip { order: 2; }
/* The show and days under the name: below the whole row on a wide screen; on
   a phone the name and this line take the width and Change and Share go to the
   next row, after the rule (Dimas, 2026-11-01, SHOW-127). */
.list-items-heading { flex-wrap: wrap; row-gap: .35rem; }
.list-items-heading .list-heading-comment { flex-basis: 100%; font-family: var(--font-body, inherit); font-weight: 400; letter-spacing: normal; line-height: 1.4; margin: 0; order: 3; text-transform: none; }
@media (max-width: 600px) {
    .list-items-heading > .section-header-title { flex-basis: 100%; }
    .list-items-heading .list-heading-comment { order: 0; }
}

/* The mark picker beside the colour (DIM-793): one button, and the marks to
   choose from under the row, all in the list's colour. */
.list-create-icon { display: flex; flex: 0 0 auto; flex-direction: column; }
.list-icon-button { align-items: center; background: var(--bg-input); border: 1px solid var(--border-input); border-radius: 7px; cursor: pointer; display: inline-flex; height: 42px; justify-content: center; width: 52px; }
.list-icon-button:hover { border-color: var(--accent-primary); }
.list-icon-grid { background: var(--bg-control); border: 1px solid var(--border-input); border-radius: 10px; display: grid; gap: 0.25rem; grid-template-columns: repeat(auto-fill, minmax(2.5rem, 1fr)); margin-top: 0.625rem; padding: 0.375rem; }
.list-icon-grid[hidden] { display: none; }
.list-icon-choice { align-items: center; background: none; border: 1px solid transparent; border-radius: 8px; cursor: pointer; display: inline-flex; height: 2.5rem; justify-content: center; width: 2.5rem; }
.list-icon-choice:hover { border-color: var(--border-input); }
.list-icon-choice.is-selected { background: rgba(var(--accent-primary-rgb), .14); border-color: var(--accent-primary); }
.list-icon-dot { border-radius: 50%; display: inline-block; height: 0.75rem; width: 0.75rem; }
.list-icon-pin { display: inline-flex; }
.list-icon-pin-icon { height: 1.35rem; stroke-width: 2; width: 1.35rem; }
/* On a phone the list's name needs the room: Share keeps its icon only. */
@media (max-width: 520px) { .list-share-chip .list-share-label { display: none; } }
.list-share-hint { color: var(--text-secondary); font-size: .9rem; margin: 0 0 0.75rem; }
.list-share-url { box-sizing: border-box; font-size: .85rem; font-weight: 500; width: 100%; }
.list-share-status { color: var(--color-my-dogs); font-size: .85rem; margin: 0.5rem 0 0; }
.list-share-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: space-between; margin-top: 1rem; }
.list-share-actions .list-share-native { width: auto; }
.list-share-actions .list-share-native[hidden] { display: none; }
.list-edit-chip { cursor: pointer; color: var(--text-secondary); text-transform: none; letter-spacing: normal; }
.list-edit-chip:hover { border-color: var(--accent-primary); color: var(--text-primary); }
.list-edit-chip .action-icon { height: 0.9rem; width: 0.9rem; }
.list-items-heading .bulk-actions-menu { font-size: .9rem; letter-spacing: normal; text-transform: none; }

/* The mark in front of a breed on the Lists page: the list's own, not a control. */
.list-item-mark { cursor: default; display: inline-flex; margin-right: 0.375rem; vertical-align: middle; } /* the shared list's rows */
.list-item-mark.list-pill-dot { margin-right: 0.5rem; }
/* The list's mark before its name in the heading (SHOW-154). */
.list-heading-mark { cursor: default; display: inline-flex; flex: 0 0 auto; } /* the heading's gap spaces it */
.list-heading-mark .list-pill-pin-icon { height: 1.15rem; width: 1.15rem; }

/* The owner's comment on a show list, under its heading (DIM-775). */
.list-comment { color: var(--text-muted); font-size: .85rem; margin: -0.5rem 0 0.75rem; }
.list-follow-badge { background: rgba(var(--color-friends-rgb),.12); border-radius: 999px; color: var(--color-friends); display: inline-block; font-size: .72rem; font-weight: 600; padding: 0.0625rem 0.5rem; }
.list-follow-badge.is-pending { background: rgba(var(--color-important-rgb),.12); color: var(--text-primary); white-space: nowrap; } /* (Dimas, 2026-10-31, SHOW-127) */
.list-pill-name-row { align-items: center; display: flex; gap: .3rem; min-width: 0; } /* (Dimas, 2026-11-01, SHOW-127) */
.list-pill-name-row .list-pill-name { flex: 0 1 auto; min-width: 0; }
.list-shared-mark { align-items: center; color: var(--color-friends); display: inline-flex; flex: none; font-size: .75rem; font-weight: 700; gap: .15rem; vertical-align: middle; }
.list-shared-icon { height: 1em; width: 1em; }
.list-items-heading .list-shared-mark { font-size: .7em; margin-left: .4rem; }
.list-pill-badges { align-items: center; display: flex; flex-wrap: wrap; gap: .375rem; margin-top: 2px; }
.list-follow-mark { align-items: center; display: inline-flex; gap: .25rem; white-space: nowrap; }
.list-follow-mark .action-icon { height: 0.75rem; width: 0.75rem; }
.list-follow-changes { color: var(--text-primary); }
.list-follow-changes > strong { display: block; margin-bottom: 6px; }
.list-follow-group { margin-top: 4px; }
.list-follow-breeds { list-style: none; margin: 2px 0 0; padding: 0; }
.list-follow-breeds li { align-items: baseline; display: flex; gap: .375rem; padding: 0.0625rem 0; }
.list-follow-breeds li::before { font-weight: 700; width: .75rem; }
.list-follow-breeds.is-added li::before { color: var(--color-friends); content: "+"; }
.list-follow-breeds.is-removed li::before { color: var(--color-my-dogs); content: "\2212"; }
.list-follow-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 10px; }

/* Create-list dialog: the main field and its colour on one line (DIM-775). */
.list-create-row { align-items: flex-end; display: flex; gap: 0.75rem; }
.list-create-main { flex: 1 1 auto; min-width: 0; }
.list-create-colour { flex: 0 0 auto; }
/* The show list's day beside its show (DIM-797), and the two rows apart. */
.list-create-day { flex: 0 1 9.5rem; min-width: 7rem; }
@media (max-width: 520px) { .list-create-day { flex-basis: 7rem; } }
.list-create-row + .list-create-row { margin-top: 0.875rem; }
/* Save and Cancel under the breed dialog's ticks (DIM-801), as in the ring's
   result dialog: a light green and a light red. */
.breed-lists-confirm { display: grid; gap: 0.5rem; grid-template-columns: 1fr 1fr; margin-top: 1.25rem; }
.breed-lists-confirm .btn-premium { width: 100%; }
.breed-lists-confirm .breed-lists-save { background: rgba(var(--color-friends-rgb), .16); border-color: rgba(var(--color-friends-rgb), .45); color: var(--text-primary); }
.breed-lists-confirm .breed-lists-save:disabled { cursor: not-allowed; opacity: .4; }
.breed-lists-confirm .breed-lists-cancel { background: rgba(239, 68, 68, .14); border-color: rgba(239, 68, 68, .4); color: var(--text-primary); }
/* The Save dialog of a shared list (DIM-798): the section first, as two chips. */
.list-save-form > * + * { margin-top: 0.875rem; }
.list-save-sections { display: grid; gap: 0.5rem; grid-template-columns: 1fr 1fr; }
.list-save-section { align-items: center; background: var(--bg-control); border: 1px solid var(--border-input); border-radius: var(--radius-sm); cursor: pointer; display: flex; font-weight: 600; gap: 0.5rem; justify-content: center; min-height: 2.875rem; padding: 0 0.75rem; }
.list-save-section:has(input:checked) { border-color: var(--accent-primary); color: var(--text-primary); background: rgba(var(--accent-primary-rgb), .12); }
.list-save-section input { accent-color: var(--accent-primary); }
/* One height for every field of the list dialogs (Dimas, 2026-10-20): the
   colour and the icon were 42 px beside fields of 44–46 px, and px does not
   follow the interface size. */
.list-create-row .input-field,
.list-create-row .list-create-colour input[type="color"],
.list-create-row .list-icon-button { box-sizing: border-box; height: 2.875rem; }

/* Show lists in two groups, upcoming then recent (DIM-775). The titles are h2s
   (the page's h1 is «Lists»; SHOW-127) that wear the h3 look of the scale. */
.list-group-title { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; margin: 1.25rem 0 0.5rem; text-transform: none; }
.list-group-title + .list-pills { margin-top: 0; }
.list-show-all { display: inline-flex; font-size: .78rem; margin-bottom: 1.25rem; padding: 0.5rem 0.875rem; width: auto; }
/* On the tab panel the secondary button's --bg-overlay is the panel's own shade,
   so it vanished (Dimas, 2026-10-31, SHOW-127): it takes the card surface and a --text-muted border (over 4:1 on the panel in both themes). */
.list-tab-panel .list-show-all { background-color: var(--bg-card); border-color: var(--text-muted); color: var(--text-primary); }
.list-tab-panel .list-show-all:hover { background-color: var(--bg-overlay); }

/* An open list's breed count, in a circle after its name (DIM-775). */
.list-count {
    align-items: center;
    background: rgba(var(--accent-primary-rgb), .14);
    border: 1px solid rgba(var(--accent-primary-rgb), .45);
    border-radius: 999px;
    color: var(--text-primary);
    display: inline-flex;
    font-size: .8rem;
    height: 1.6rem;
    justify-content: center;
    letter-spacing: 0;
    margin-left: 0.35rem;
    min-width: 1.6rem;
    padding: 0 0.4rem;
    vertical-align: middle;
}

/* A breed on a show list, in the timetable and on the dashboard: the list's pin
   in its colour, where other lists have their dot (DIM-775). */
.breed-list-pin { display: inline-flex; vertical-align: -0.125rem; }
.breed-list-pin-icon { height: 0.95rem; stroke-width: 2; width: 0.95rem; }

/* The venue map button on the dashboard's Rings line, after the rule at the
   right; the heading's capitals and spacing are not the button's. */
.section-header .section-header-action { font-size: .8rem; letter-spacing: normal; margin-left: 0; order: 1; text-transform: none; }
/* An icon before the heading's text, sized to it (SHOW-90). */
.section-header .section-header-icon { flex: none; height: 1.15em; stroke: currentColor; width: 1.15em; }
/* The heading is a nowrap row; on a narrow phone the button gives up padding. */
.passkeys-section .section-header { flex-wrap: nowrap; }
.passkeys-section .section-header-action { flex: none; padding: .4rem .75rem; white-space: nowrap; width: auto; }
@media (max-width: 420px) { .passkeys-section .section-header { gap: .5rem; } .passkeys-section .section-header-action { font-size: .75rem; padding: .35rem .6rem; } }

/* The dashboard's heading sits inside the row as an h2 of its own, so the menu
   is not nested in a heading (SHOW-65). */
.section-header-title { color: inherit; font: inherit; letter-spacing: inherit; margin: 0; text-transform: inherit; }
/* An h2 holding an icon, a word and a tag side by side; a button stays beside it, outside the heading. */
.section-header-title-row { align-items: center; display: flex; gap: 0.75rem; }
/* A page title with a control on its line (the country picker of Expositions). */
.page-title-row { align-items: center; display: flex; flex-wrap: wrap; gap: 0 0.75rem; }
.page-title-row .page-title { margin: 0; }
/* A card's title is the show's name: an h3 around the link, sized as the link was. */
.show-card-heading-name { font-size: 1.05rem; font-weight: 700; letter-spacing: normal; line-height: 1; text-transform: none; }
/* The year the past shows turn into: an H3 with the count beside it, no rule line. */
.show-year-heading { align-items: center; display: flex; gap: 0.5rem; margin: 1rem 0 0.5rem; }

/* The Add calendar menu after a section heading's rule (SHOW-65). A <details>,
   so it opens with no script; app.js only closes it on an outside click. */
.calendar-subscribe { flex: none; order: 1; position: relative; }
.calendar-subscribe-toggle {
    align-items: center;
    cursor: pointer;
    display: inline-flex;
    font-family: var(--font-body, inherit);
    font-weight: 600;
    gap: 0.375rem;
    letter-spacing: normal;
    list-style: none;
    text-transform: none;
    user-select: none;
}
.calendar-subscribe-toggle::-webkit-details-marker { display: none; }
.calendar-subscribe-toggle .action-icon { color: var(--accent-text); height: 1rem; width: 1rem; }
.calendar-subscribe-menu {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, .4);
    display: flex;
    flex-direction: column;
    max-width: calc(100vw - 2rem);
    min-width: 12.5rem;
    overflow: hidden;
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: var(--z-popover);
}
/* An open menu lies over the bottom bar, not under it: on a phone the banner's
   menu ran behind the bar (Dimas, 2026-11-01, SHOW-127). */
.calendar-subscribe[open] .calendar-subscribe-menu { z-index: calc(var(--z-chrome) + 1); }
.calendar-subscribe-menu a,
.calendar-subscribe-menu button {
    background: none;
    border: 0;
    color: var(--text-secondary);
    cursor: pointer;
    font: 500 .85rem var(--font-body, inherit);
    letter-spacing: normal;
    padding: 0.625rem 0.875rem;
    text-align: left;
    text-decoration: none;
    text-transform: none;
    white-space: nowrap;
}
.calendar-subscribe-menu a:hover,
.calendar-subscribe-menu button:hover { background: var(--bg-overlay); color: var(--text-primary); }
.calendar-subscribe-menu a:focus-visible,
.calendar-subscribe-menu button:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }

/* The country dialog of the Add calendar menu (SHOW-65). It sits inside a
   section heading, so it takes back the heading's letter case and spacing. */
.calendar-countries-modal { font: 400 1rem/1.4 var(--font-body, inherit); letter-spacing: normal; text-transform: none; }
.calendar-countries-modal .modal-body { display: flex; flex-direction: column; gap: 0.75rem; }
.calendar-countries-hint { color: var(--text-secondary); font-size: .85rem; line-height: 1.4; margin: 0; }
.calendar-country { color: var(--text-primary); cursor: pointer; }
.calendar-country span { font-size: .95rem; }
.calendar-country input { accent-color: var(--accent-primary); height: 18px; width: 18px; }
.calendar-countries-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: flex-end; }
.calendar-countries-actions .btn-premium { width: auto; }
.calendar-countries-actions .btn-premium:disabled { cursor: not-allowed; opacity: .5; }

/* A show over several halls: one row of ring buttons per hall, its letter
   first, the buttons in shared columns across the rows (DIM-777). */
.schedule-ring-filter.has-halls { display: flex; flex-direction: column; gap: 0.375rem; }
.ring-hall-row { align-items: center; display: grid; gap: 0.375rem; grid-template-columns: 1.25rem 1fr; }
.ring-hall-label { color: var(--accent-text); font: 700 .8rem var(--font-display); text-align: center; }
/* "A:" before a ring's name in a show of several halls (Dimas, 2026-10-21, DIM-811). */
.ring-hall-prefix { color: var(--accent-text); }
/* Each hall its own colour, by its place in the layout (DIM-812). Mid tones,
   one value for both themes like the accent: each reads on white and on the
   dark ground, and they stay apart from the orange and from each other. */
.ring-hall-label.hall-2, .ring-hall-prefix.hall-2 { color: var(--hall-2); }
.ring-hall-label.hall-3, .ring-hall-prefix.hall-3 { color: var(--hall-3); }
.ring-hall-label.hall-4, .ring-hall-prefix.hall-4 { color: var(--hall-4); }
.ring-hall-buttons { display: grid; gap: 0.375rem; grid-template-columns: repeat(var(--ring-columns, 1), minmax(0, 1fr)); }

/* The Rings line and the filters under it stay on screen while the ring cards
   or the timetable scroll beneath, folded or not (Dimas, 2026-10-20). Parked
   under the fixed header, on the page's own colour so nothing shows through. */
.rings-sticky {
    background: var(--bg-base);
    padding: 0.5rem 0 0.75rem;
    position: sticky;
    top: var(--header-height);
    z-index: var(--z-content);
}
.rings-sticky-headed { margin-top: 2rem; }   /* the dashboard's, which carries the Rings heading */
.rings-sticky > .section-header { margin-top: 0; }
.rings-sticky .schedule-search { margin-bottom: 0; }

/* Each ring's heading sticks under the filter block while its ring is on
   screen, and the next ring's heading pushes it out (Dimas, 2026-10-20): a
   sticky element stays inside its own section, so the section's end is where
   it lets go. --rings-sticky-height is the block's measured height, kept by
   watchRingsSticky(), since folding the ring buttons changes it. */
.rings-sticky ~ .schedule-ring-tables .schedule-ring-table > h2 {
    background: var(--bg-base);
    margin-bottom: 0;
    padding: 0.375rem 0 0.625rem;
    position: sticky;
    top: calc(var(--header-height) + var(--rings-sticky-height, 0px));
    z-index: calc(var(--z-content) - 1);
}

/* One magnifier for the page (DIM-777). It lives in the heading of the ring at
   the top — placeRingSearch() moves it there — so it rides with that heading,
   pushed out with it, and never hangs over a table. "Ring N" has a fixed width
   reserved, so it never wraps, and the open field takes everything from there
   to the magnifier, over the judge (Dimas, 2026-10-20; was 70%, then measured).
   .ring-search-band is only its home before the script places it, and where it
   waits when no ring is shown. */
.rings-sticky ~ .schedule-ring-tables { --ring-label-w: 5.3rem; }   /* "Ringue 88", the widest label in any language (84.3px at 1.05rem) */
.rings-sticky ~ .schedule-ring-tables .schedule-ring-table > h2 { align-items: center; flex-wrap: nowrap; }
/* One line: a long judge's name ends in an ellipsis rather than wrapping under "Ring N". */
.rings-sticky ~ .schedule-ring-tables .schedule-ring-table > h2 > small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rings-sticky ~ .schedule-ring-tables .schedule-ring-table > h2 > span:first-child { flex: 0 0 var(--ring-label-w); white-space: nowrap; }
.ring-search-band { height: 0; position: relative; }
.ring-search-band-inner { align-items: center; display: flex; gap: 0.375rem; height: 2.75rem; justify-content: flex-end; position: absolute; right: 0; top: 0; z-index: 1; }
.schedule-ring-table > h2 > .ring-search-band-inner, .schedule-own-view > h2 > .ring-search-band-inner { bottom: 0; height: auto; }
/* Closed, the magnifier stands in the heading's own row, so only the heading
   that carries it gives up room, and only as much as the button takes: every
   heading used to keep 6.5rem free on its right, and a judge's name was cut
   short in the left column with nothing beside it (Dimas, 2026-10-31). Zero
   height, so the 2rem button does not make its heading taller than the rest.
   Open, it is lifted out again and runs over the judge, on the page's background. */
.schedule-ring-table > h2 > .ring-search-band-inner:not(.is-open) { align-self: center; height: 0; margin-left: auto; padding-left: 0.5rem; position: static; }
.schedule-ring-table > h2 > .ring-search-band-inner.is-open { background: var(--bg-base); }
/* 30px, not 32: a 2rem button centred in the heading stood a quarter of a pixel
   above its top, under the stuck filter block, and lost its top border on a
   Retina screen (Dimas, 2026-10-31). */
.schedule-ring-table > h2 .ring-search-btn { height: 1.875rem; }
.ring-search-band-inner.is-open { left: var(--ring-search-left, calc(var(--ring-label-w, 5.3rem) + 0.5rem)); }
.ring-search-band-inner .ring-search { animation: ring-search-slide .18s ease-out; flex: 1 1 auto; margin: 0; min-width: 0; }
.ring-search-band-inner .ring-search .schedule-search-input { font-size: .8rem; padding-bottom: 0.375rem; padding-top: 0.375rem; }
/* An orange border at rest, or "Search" reads as loose text beside the judge (Dimas, 2026-10-31). */
.ring-search-btn { align-items: center; background: var(--bg-base); border: 1px solid var(--accent-primary); border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: inline-flex; flex: 0 0 auto; font: 700 .78rem var(--font-display); gap: 0.3rem; height: 2rem; justify-content: center; min-width: 2rem; padding: 0 0.5rem; transition: var(--transition-premium); }
/* The word beside the magnifier (Dimas, 2026-10-20); it steps aside while the field is out. */
.ring-search-band-inner.is-open .ring-search-word { display: none; }
.ring-search-btn:hover, .ring-search-band-inner.is-open .ring-search-btn { border-color: var(--accent-primary); color: var(--accent-text); }
.ring-search-btn .action-icon { height: 1.1rem; width: 1.1rem; }
@keyframes ring-search-slide { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@media (prefers-reduced-motion: reduce) { .ring-search-band-inner .ring-search { animation: none; } }

/* The day beside "Rings" on the dashboard: the same weight, a quieter colour. */
.rings-heading-date { color: var(--text-muted); letter-spacing: 0.02em; text-transform: none; white-space: nowrap; } /* "сб, 10 жов" as written, not shouted with the heading (SHOW-134) */

/* "By group/breed": a group's name beside its number may run longer than the
   room kept for "Ring N", so it takes its own width (DIM-777). */
.rings-sticky ~ .schedule-ring-tables .schedule-group-table > h2 > .schedule-group-label { flex: 0 0 auto; }

/* Install suggestion (SHOW-118) */
.install-hint { align-items: start; background: var(--card-bg, rgba(255, 255, 255, .06)); border: 1px solid var(--border-color, rgba(255, 255, 255, .12)); border-radius: 12px; column-gap: .5rem; display: grid; grid-template-areas: "text close" "button close"; grid-template-columns: minmax(0, 1fr) auto; margin: 0 0 1rem; padding: .75rem .5rem .75rem 1rem; row-gap: .625rem; }
.install-hint[hidden], .install-hint [hidden] { display: none; }
.install-hint-text { color: var(--text-secondary); font-size: .85rem; grid-area: text; line-height: 1.45; margin: 0; min-width: 0; }
.install-hint-share { color: var(--accent-text); height: 1.15em; margin: 0 .1em; vertical-align: -0.2em; width: 1.15em; }
.install-hint-share-word { white-space: nowrap; }
/* .btn-premium is a full-width block; here it is a button's width under the text. */
.install-hint-button { grid-area: button; justify-self: start; padding: .5rem 1.25rem; width: auto; }
.install-hint-close { align-items: center; grid-area: close; background: none; border: 0; color: var(--text-secondary); cursor: pointer; display: flex; flex-shrink: 0; height: 2.25rem; justify-content: center; padding: 0; width: 2.25rem; }

/* ==========================================================================
   Accent themes (SHOW-129)

   Settings → Appearance → Theme. Default is everything above, untouched: no
   rule here applies without data-accent="contrast" or "tinted" on <html>.

   Contrast keeps the solid orange and puts dark text on it. Tinted drops the
   solid fill for a soft tint, an outline and orange text. Both set orange text
   (--accent-text) and the focus ring to a darker orange on the light palette.

   The tokens come in dark and light, resolved the way the palette is: the
   explicit choice, and prefers-color-scheme for "follow the device".
   The rules after them read the tokens and are written once for both themes.
   ========================================================================== */

/* --- Contrast: dark palette (also the base for light) --- */
:root[data-accent="contrast"] {
    --accent-text: #FF7A00;
    --focus-ring: #FF7A00;
    --badge-text: #060913;
    --ctl-bg: #FF7A00;
    --ctl-bg-card: #FF7A00;
    --ctl-bg-hover: #E06B00;
    --ctl-bg-hover-card: #E06B00;
    --ctl-border: #FF7A00;
    --ctl-border-hover: #E06B00;
    --ctl-text: #060913;
    --ctl-border-w: 1px;
    --ctl-ring-w: 0px;
    --day-bg: rgba(255, 122, 0, 0.8);
    --day-border: #FF7A00;
    --day-sub: #060913;
    --day-num: #060913;
    --btn-shadow: 0 4px 15px rgba(255, 122, 0, 0.2);
    --btn-shadow-hover: 0 6px 20px rgba(255, 122, 0, 0.35);
    --float-shadow: 0 4px 15px rgba(255, 122, 0, 0.35);
    --hub-bg: linear-gradient(160deg, #FF7A00 0%, rgba(255, 122, 0, 0.78) 100%);
    --hub-bg-hover: linear-gradient(160deg, #FF7A00 0%, rgba(255, 122, 0, 0.78) 100%);
    --hub-border: var(--bg-surface);
    --hub-border-w: 3px;
    --hub-ring: 0px;
    --hub-icon: #FFFFFF;
    --hub-shadow: 0 6px 18px rgba(255, 122, 0, 0.45);
    --hub-shadow-hover: 0 8px 22px rgba(255, 122, 0, 0.6);
}

/* Light: orange stops being the colour of small text (SHOW-131). The words are
   the ink; orange stays as a mark beside them (see the marks below), as the
   fill of a control with white text on it, and as the large bold text WCAG
   allows at 3:1. The fill is #C25400 (white on it: 4.6:1). */
:root[data-accent="contrast"][data-theme="light"],
:root[data-accent="contrast"][data-theme="system"] {
    --accent-text: var(--text-primary);
    --accent-text-large: #E56E00;
    --focus-ring: #B84A00;
    --badge-text: #FFFFFF;
    --ctl-bg: #C25400;
    --ctl-bg-card: #C25400;
    --ctl-bg-hover: #B44E00;
    --ctl-bg-hover-card: #B44E00;
    --ctl-bg-active: #A84800;
    --ctl-border: #C25400;
    --ctl-border-hover: #B44E00;
    --ctl-text: #FFFFFF;
    --day-bg: #C25400;
    --day-border: #C25400;
    --day-sub: #FFFFFF;
    --day-num: #FFFFFF;
    --btn-shadow: 0 4px 15px rgba(194, 84, 0, 0.2);
    --btn-shadow-hover: 0 6px 20px rgba(194, 84, 0, 0.35);
    --float-shadow: 0 4px 15px rgba(194, 84, 0, 0.35);
    --hub-bg: #C25400;
    --hub-bg-hover: #B44E00;
    --hub-bg-active: #A84800;
    --hub-icon: #FFFFFF;
    --hub-shadow: 0 6px 18px rgba(194, 84, 0, 0.45);
    --hub-shadow-hover: 0 8px 22px rgba(194, 84, 0, 0.6);
}

@media (prefers-color-scheme: dark) {
    :root[data-accent="contrast"][data-theme="system"] {
        --accent-text: #FF7A00;
        --accent-text-large: var(--accent-text);
        --focus-ring: #FF7A00;
        --badge-text: #060913;
        --ctl-bg: #FF7A00;
        --ctl-bg-card: #FF7A00;
        --ctl-bg-hover: #E06B00;
        --ctl-bg-hover-card: #E06B00;
        --ctl-border: #FF7A00;
        --ctl-border-hover: #E06B00;
        --ctl-text: #060913;
        --day-bg: rgba(255, 122, 0, 0.8);
        --day-border: #FF7A00;
        --day-sub: #060913;
        --day-num: #060913;
        --btn-shadow: 0 4px 15px rgba(255, 122, 0, 0.2);
        --btn-shadow-hover: 0 6px 20px rgba(255, 122, 0, 0.35);
        --float-shadow: 0 4px 15px rgba(255, 122, 0, 0.35);
        --hub-bg: linear-gradient(160deg, #FF7A00 0%, rgba(255, 122, 0, 0.78) 100%);
        --hub-bg-hover: linear-gradient(160deg, #FF7A00 0%, rgba(255, 122, 0, 0.78) 100%);
        --hub-icon: #FFFFFF;
        --hub-shadow: 0 6px 18px rgba(255, 122, 0, 0.45);
        --hub-shadow-hover: 0 8px 22px rgba(255, 122, 0, 0.6);
    }
}

/* --- Tinted: dark palette --- */
:root[data-accent="tinted"] {
    --accent-text: #FF7A00;
    --focus-ring: #FF7A00;
    --badge-text: #060913;
    --ctl-bg: #35231D;
    --ctl-bg-card: #3A2927;
    --ctl-bg-hover: #4D2E19;
    --ctl-bg-hover-card: #513322;
    --ctl-border: #FF7A00;
    --ctl-border-hover: #FF7A00;
    --ctl-text: #FF7A00;
    --ctl-border-w: 1.5px;
    --ctl-ring-w: 1px; /* (Dimas, 2026-10-31, SHOW-127) */
    --day-bg: #35231D;
    --day-border: #FF7A00;
    --day-sub: #FF7A00;
    --day-num: #FF7A00;
    --btn-shadow: 0 0 0 0 transparent;
    --btn-shadow-hover: 0 0 0 0 transparent;
    --float-shadow: 0 0 0 0 transparent;
    --hub-bg: #35231D;
    --hub-bg-hover: #4D2E19;
    --hub-border: #FF7A00;
    --hub-border-w: 1.5px;
    --hub-ring: 3px;
    --hub-icon: #FFFFFF;
    /* The hub glows (Dimas, 2026-10-31, SHOW-127). */
    --hub-shadow: 0 0 18px 2px rgba(255, 122, 0, 0.55);
    --hub-shadow-hover: 0 0 24px 4px rgba(255, 122, 0, 0.7);
}

/* --- Tinted: light palette --- */
:root[data-accent="tinted"][data-theme="light"],
:root[data-accent="tinted"][data-theme="system"] {
    --accent-text: var(--text-primary);
    --accent-text-large: #E56E00;
    --focus-ring: #B84A00;
    --ctl-bg: #FFEAD6;
    --ctl-bg-card: #FFEAD6;
    --ctl-bg-hover: #FFDCBD;
    --ctl-bg-hover-card: #FFDCBD;
    --ctl-border: #C2410C;
    --ctl-border-hover: #C2410C;
    --ctl-text: #9A3412;
    --day-bg: #FFEAD6;
    --day-border: #C2410C;
    --day-sub: #9A3412;
    --day-num: #9A3412;
    --hub-bg: #FFEAD6;
    --hub-bg-hover: #FFDCBD;
    --hub-border: #C2410C;
    --hub-icon: #9A3412;
    --hub-shadow: 0 0 18px 2px rgba(194, 65, 12, 0.45); /* (Dimas, 2026-10-31, SHOW-127) */
    --hub-shadow-hover: 0 0 24px 4px rgba(194, 65, 12, 0.6);
}

@media (prefers-color-scheme: dark) {
    :root[data-accent="tinted"][data-theme="system"] {
        --accent-text: #FF7A00;
        --accent-text-large: var(--accent-text);
        --focus-ring: #FF7A00;
        --ctl-bg: #35231D;
        --ctl-bg-card: #3A2927;
        --ctl-bg-hover: #4D2E19;
        --ctl-bg-hover-card: #513322;
        --ctl-border: #FF7A00;
        --ctl-border-hover: #FF7A00;
        --ctl-text: #FF7A00;
        --day-bg: #35231D;
        --day-border: #FF7A00;
        --day-sub: #FF7A00;
        --day-num: #FF7A00;
        --hub-bg: #35231D;
        --hub-bg-hover: #4D2E19;
        --hub-border: #FF7A00;
        --hub-icon: #FFFFFF;
        --hub-shadow: 0 0 18px 2px rgba(255, 122, 0, 0.55); /* (Dimas, 2026-10-31, SHOW-127) */
        --hub-shadow-hover: 0 0 24px 4px rgba(255, 122, 0, 0.7);
    }
}

/* Tinted: the active list pill and the dashboard banner strip take the control border (Dimas, 2026-10-31, SHOW-127). */
:root[data-accent="tinted"] .list-pill.active { border-color: var(--ctl-border); }
:root[data-accent="tinted"] .dashboard-banner::before { background: var(--ctl-border); }

/* --- The solid-orange controls, for both accent themes --- */
/* Controls with a border of their own take the colour and width; the ones
   without one draw the outline as an inset shadow, so no box changes size. */
:root:is([data-accent="contrast"], [data-accent="tinted"]) .guest-account-links a:last-child {
    background: var(--ctl-bg);
    border-color: var(--ctl-border);
    border-width: var(--ctl-border-w);
    color: var(--ctl-text);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .guest-account-links a:last-child:hover {
    background: var(--ctl-bg-hover);
    border-color: var(--ctl-border-hover);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .active-show-date-btn.active {
    background-color: var(--ctl-bg);
    box-shadow: inset 0 0 0 var(--ctl-ring-w) var(--ctl-border);
    color: var(--ctl-text);
}

/* The date row sits in the card's bottom corners, which the card clips
   (overflow: hidden). A solid fill hid the clip; an outline drawn inside the
   button does not, so the outer buttons take the card's inner corner. */
:root:is([data-accent="contrast"], [data-accent="tinted"]) .active-show-date-btn:first-child {
    border-bottom-left-radius: calc(var(--radius-md) - 1px);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .active-show-date-btn:last-child {
    border-bottom-right-radius: calc(var(--radius-md) - 1px);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .year-picker-year-active {
    background: var(--ctl-bg);
    border-color: var(--ctl-border);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .btn-premium-primary {
    background-color: var(--ctl-bg);
    box-shadow: inset 0 0 0 var(--ctl-ring-w) var(--ctl-border), var(--btn-shadow);
    color: var(--ctl-text);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .btn-premium-primary:hover {
    background-color: var(--ctl-bg-hover);
    box-shadow: inset 0 0 0 var(--ctl-ring-w) var(--ctl-border-hover), var(--btn-shadow-hover);
}

/* "Not today" greys Enable out (SHOW-107). The two rules above outrank that
   rule, so Contrast and Tinted painted it as a full call to action; it stays
   the small grey button it is in Default. */
:root:is([data-accent="contrast"], [data-accent="tinted"]) .steward-offer-banner.is-later .btn-premium,
:root:is([data-accent="contrast"], [data-accent="tinted"]) .steward-offer-banner.is-later .btn-premium:hover {
    background: transparent;
    box-shadow: none;
    color: var(--text-muted);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .bar-tab-hub {
    background: var(--hub-bg);
    border-color: var(--hub-border);
    border-width: var(--hub-border-w);
    box-shadow: 0 0 0 var(--hub-ring) var(--bg-surface), var(--hub-shadow);
    color: var(--hub-icon);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .bar-tab-hub:hover,
:root:is([data-accent="contrast"], [data-accent="tinted"]) .bar-tab-hub.active {
    background: var(--hub-bg-hover);
    border-color: var(--hub-border);
    box-shadow: 0 0 0 var(--hub-ring) var(--bg-surface), var(--hub-shadow-hover);
    color: var(--hub-icon);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .show-title-filter-chip[aria-pressed="true"] {
    background: var(--ctl-bg);
    border-color: var(--ctl-border);
    border-width: var(--ctl-border-w);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .modal-overlay .show-map-x {
    background-color: var(--ctl-bg);
    border: var(--ctl-border-w) solid var(--ctl-border);
    box-shadow: var(--float-shadow);
    color: var(--ctl-text);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .modal-overlay .show-map-x:hover {
    background-color: var(--ctl-bg-hover);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-view-option.active,
:root:is([data-accent="contrast"], [data-accent="tinted"]) button.schedule-view-option.active {
    background: var(--ctl-bg-card);
    box-shadow: inset 0 0 0 var(--ctl-ring-w) var(--ctl-border);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-date-tab.active {
    background: var(--day-bg);
    border-color: var(--day-border);
    border-width: var(--ctl-border-w);
    color: var(--accent-text);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-date-tab.active span { color: var(--day-sub); }
:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-date-tab.active strong { color: var(--day-num); }

:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-ring-filter-btn.active {
    background: var(--ctl-bg);
    border-color: var(--ctl-border);
    border-width: var(--ctl-border-w);
    color: var(--ctl-text);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-ring-filter-btn.active:hover {
    background: var(--ctl-bg-hover);
    border-color: var(--ctl-border-hover);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .import-tab.active {
    background-color: var(--ctl-bg-card);
    box-shadow: inset 0 0 0 var(--ctl-ring-w) var(--ctl-border);
    color: var(--ctl-text);
}

:root:is([data-accent="contrast"], [data-accent="tinted"]) .bulk-fab-trigger {
    background-color: var(--ctl-bg);
    border: var(--ctl-border-w) solid var(--ctl-border);
    color: var(--ctl-text);
}
:root:is([data-accent="contrast"], [data-accent="tinted"]) .bulk-fab-trigger:hover,
:root:is([data-accent="contrast"], [data-accent="tinted"]) .bulk-fab-trigger:focus-visible {
    background-color: var(--ctl-bg-hover);
}

/* The "now" badge keeps its orange fill; its text is the dark ink in both
   palettes (the default is the page background, which is near-white in light).
   The paler .is-ahead badge has its own colours and is left alone. */
:root:is([data-accent="contrast"], [data-accent="tinted"]) .schedule-now-badge:not(.is-ahead) {
    color: var(--badge-text);
}

/* The hub's own override above would hide the pending ring (Default draws a
   translucent ring and a glow while a tap waits for its page). Keep both, in
   the accent's own colours: an orange ring replaces the white one, which
   would not show on a light hub or a light page. */
:root:is([data-accent="contrast"], [data-accent="tinted"]) .bar-tab-hub.nav-pending {
    box-shadow: 0 0 0 3px rgba(var(--accent-primary-rgb), .5), var(--hub-shadow-hover);
    color: var(--hub-icon);
}

/* --- Light palette, Contrast: the pressed state, the Now badge (SHOW-131) ---
   Written for the explicit light choice and, inside the media query, for
   "follow the device"; the dark palette has no pressed colour of its own. */
:root[data-accent="contrast"][data-theme="light"] :is(.guest-account-links a:last-child, .active-show-date-btn.active, .year-picker-year-active, .btn-premium-primary, .show-title-filter-chip[aria-pressed="true"], .schedule-ring-filter-btn.active, .bulk-fab-trigger, .modal-overlay .show-map-x, .schedule-view-option.active, .import-tab.active):active {
    background-color: var(--ctl-bg-active);
    border-color: var(--ctl-bg-active);
}
:root[data-accent="contrast"][data-theme="light"] .bar-tab-hub:active {
    background: var(--hub-bg-active);
}
:root[data-accent="contrast"][data-theme="light"] .schedule-now-badge:not(.is-ahead) {
    background: var(--ctl-bg);
}
@media (prefers-color-scheme: light) {
    :root[data-accent="contrast"][data-theme="system"] :is(.guest-account-links a:last-child, .active-show-date-btn.active, .year-picker-year-active, .btn-premium-primary, .show-title-filter-chip[aria-pressed="true"], .schedule-ring-filter-btn.active, .bulk-fab-trigger, .modal-overlay .show-map-x, .schedule-view-option.active, .import-tab.active):active {
        background-color: var(--ctl-bg-active);
        border-color: var(--ctl-bg-active);
    }
    :root[data-accent="contrast"][data-theme="system"] .bar-tab-hub:active {
        background: var(--hub-bg-active);
    }
    :root[data-accent="contrast"][data-theme="system"] .schedule-now-badge:not(.is-ahead) {
        background: var(--ctl-bg);
    }
}

/* --- Light palette, Contrast and Tinted: orange as a mark, not as words ---
   Small text is the ink (--accent-text). The brand orange stays visible as a
   non-text sign beside it: a dot before the time, a 2px underline under a link
   in running text. The open tab is the one exception: its icon and label are
   dark orange #B84A00 (4.83:1 on the tab's tint), no bar (Dimas, 2026-10-31). Drawn with ::before, ::after and
   text-decoration, so no markup changes. Focus is the ring alone. */
:root:is([data-accent="contrast"], [data-accent="tinted"])[data-theme="light"] .bar-tab.active:not(.bar-tab-hub) {
    color: #B84A00;
}
:root:is([data-accent="contrast"], [data-accent="tinted"])[data-theme="light"] .schedule-table-time::before {
    background: #FF7A00;
    border-radius: 50%;
    content: '';
    display: inline-block;
    height: 0.3rem;
    margin-right: 0.2rem;
    vertical-align: 0.1em;
    width: 0.3rem;
}
@media (prefers-color-scheme: light) {
    :root:is([data-accent="contrast"], [data-accent="tinted"])[data-theme="system"] .bar-tab.active:not(.bar-tab-hub) {
        color: #B84A00;
    }
    :root:is([data-accent="contrast"], [data-accent="tinted"])[data-theme="system"] .schedule-table-time::before {
        background: #FF7A00;
        border-radius: 50%;
        content: '';
        display: inline-block;
        height: 0.3rem;
        margin-right: 0.2rem;
        vertical-align: 0.1em;
        width: 0.3rem;
    }
}

/* The sample on Settings → Appearance → Theme: a small button in each style.
   Literal colours, because the page shows all three at once. */
.accent-choice-sample { align-items: center; border: 1px solid transparent; border-radius: var(--radius-sm); display: inline-flex; flex: 0 0 auto; font: 700 .9rem var(--font-display); height: 2.5rem; justify-content: center; width: 3.5rem; }
.accent-sample-default { background: #FF7A00; color: #fff; }
.accent-sample-contrast { background: #FF7A00; color: #060913; }
.accent-sample-tinted { background: #35231D; border-color: #FF7A00; color: #FF7A00; }
:root[data-theme="light"] .accent-sample-tinted { background: #FFEAD6; border-color: #C2410C; color: #9A3412; }
@media (prefers-color-scheme: light) {
    :root[data-theme="system"] .accent-sample-tinted { background: #FFEAD6; border-color: #C2410C; color: #9A3412; }
}

/* End of accent themes (SHOW-129). Every rule between "Accent themes (SHOW-129)" and
   this line is scoped by data-accent; test_accent_choice checks that (SHOW-159). */

/* No inline styles (SHOW-155): what used to sit in style="" lives here. A value
   that comes from data arrives as a custom property on the element. */
.mt-10 { margin-top: 0.625rem; }
.mt-12 { margin-top: 0.75rem; }
.mt-20 { margin-top: 1.25rem; }
.text-muted { color: var(--text-muted); }
.empty-state-spaced { margin-top: 2.5rem; }
.empty-state-roomy { padding: 1.875rem; }
.empty-state-padded { padding: 1.5rem; }
.list-items-empty { color: var(--text-muted); padding: 1.5rem; text-align: center; }
.ring-toggle-cell { padding: 0.375rem; text-align: center; }
.user-role-line { margin-top: 0.25rem; }
[data-action="open-ring-update"], [data-action="open-breed-lists"], .is-clickable { cursor: pointer; }
.breed-item-name { font-family: var(--font-display); font-weight: 600; padding-left: 0.3rem; }
/* A breed's note in a list reads as an aside: italic (Dimas, 2026-11-01, SHOW-127). */
.breed-item-note { font-style: italic; }
.btn-premium.breed-lists-settings { display: block; margin-top: 1.25rem; text-align: center; }
.db-error-banner { background-color: rgba(var(--color-my-dogs-rgb), 0.15); border: 1px solid rgba(var(--color-my-dogs-rgb), 0.3); border-radius: 10px; color: var(--color-my-dogs); font-size: 0.9rem; margin-bottom: 1rem; padding: 0.875rem; }
.usage-chart-seg, .usage-chart-new { height: var(--bar, 0%); }
.breed-list-dot, .list-pill-dot, .list-icon-dot { background-color: var(--mark-color); }
.breed-list-pin, .list-pill-pin, .list-icon-pin { color: var(--mark-color); }

/* Values computed in JS arrive as custom properties (SHOW-155). */
.schedule-drag-ghost { height: var(--ghost-height); left: var(--ghost-left); top: var(--ghost-top); width: var(--ghost-width); }
.reorder-panel { bottom: var(--panel-bottom, 0px); }
.offline-banner { bottom: var(--banner-bottom, 0px); }
.ptr-indicator { transform: translateY(var(--ptr-y, 0px)); }
.ptr-indicator.is-pulling { transition: none; }
.ptr-indicator.ptr-release { transition: transform 0.3s ease; }
.test-dashboard-summary .test-run-bar { width: var(--share, 0%); }
.test-dashboard-summary .test-run-bar.is-resetting { transition: none; }
#catalogue-explain-modal .catalogue-explain-meter-fill { width: var(--share, 0%); }
.avatar-crop-stage > img { height: var(--crop-height); left: var(--crop-left); top: var(--crop-top); width: var(--crop-width); }
.catalogue-fit-row.is-wrapped { grid-template-columns: repeat(var(--fit-columns, 1), 1fr); }
.suggestion-new { font-style: italic; }
.toast.toast-leaving { opacity: 0; transform: translateY(-20px); }
.toast.toast-leaving-centered { opacity: 0; transform: translate(-50%, -20px); }

/* Settings → Judges: quick search by name and a country list (SHOW-186). */
.judges-filter { align-items: center; display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1rem; }
.judges-filter .breed-search-input { flex: 1 1 16rem; margin: 0; }
.judges-filter-country { flex: 0 1 14rem; min-height: 40px; }
.judge-card[hidden] { display: none; }
/* About the show → Judges: names in white, not in the link orange; the monogram keeps the accent (SHOW-186). */
.show-info-section.judges-directory .judge-card-identity a { color: var(--text-primary); }
.show-info-section.judges-directory .judge-card-identity a:hover { color: var(--accent-text); }

/* Settings -> Judge -> Show history: what the judge does at the show (SHOW-186). */
.judge-history-role { border: 1px solid var(--border-highlight); border-radius: 999px; color: var(--text-secondary); font-size: 0.75rem; font-weight: 700; padding: 0.05rem 0.5rem; }
.judge-show-list a strong { flex: 1 1 auto; }

/* Settings -> Judges -> Possible duplicates: the printed name beside our judge, and the two answers (SHOW-186). */
.judge-duplicates-intro { color: var(--text-secondary); margin: 0 0 1rem; max-width: 60rem; }
.judge-duplicates { display: grid; gap: 0.75rem; }
.judge-duplicate { display: grid; gap: 1rem; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; align-items: start; margin-bottom: 0; }
.judge-duplicate-side { display: grid; gap: 0.35rem; min-width: 0; }
.judge-duplicate-label { color: var(--text-muted); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.judge-duplicate-name { font-weight: 700; overflow-wrap: anywhere; }
.judge-duplicate-name a { color: var(--text-primary); }
.judge-duplicate-shows, .judge-duplicate-fci { color: var(--text-secondary); font-size: 0.85rem; }
.judge-duplicate-candidate { align-items: center; display: flex; flex-wrap: wrap; gap: 0.5rem 0.75rem; justify-content: space-between; }
.judge-duplicate-other { align-self: end; }
@media (max-width: 760px) { .judge-duplicate { grid-template-columns: minmax(0, 1fr); } .judge-duplicate-other { align-self: start; } }

/* Settings -> Breed clubs: the card shows what its state allows; the buttons change it in place (SHOW-180). */
.club-admin-card[data-has-file="0"] [data-club-logo],
.club-admin-card[data-has-file="1"] .club-admin-shield,
.club-admin-card[data-has-file="0"] [data-club-approve],
.club-admin-card[data-has-file="0"] [data-club-reject],
.club-admin-card[data-status="approved"] [data-club-approve] { display: none; }
.club-admin-card.is-busy .club-admin-actions { opacity: 0.5; pointer-events: none; }

/* About the show -> Monographic and other shows: the day with its venue, then each show as a
   title line, one judge per line and the organiser underneath (Dimas's layout, 2026-11-02). */
.club-day-head { align-items: baseline; border-bottom: 1px solid var(--border-color); display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; justify-content: space-between; padding-bottom: 0.6rem; }
.club-day-head .show-info-day-title { margin: 0.25rem 0 0; }
.club-day-venue, .club-show-venue { align-items: center; color: var(--text-secondary); display: inline-flex; gap: 0.35rem; }
.club-day-pin { flex: 0 0 auto; height: 18px; width: 18px; }
.club-show { border-top: 1px solid var(--border-color); padding: 0.85rem 0; }
.club-day-head + .club-show { border-top: 0; }
.club-show:last-child { padding-bottom: 0; }
.club-show p { margin: 0; }
.club-show p.club-show-title { font-weight: 700; line-height: 1.5; margin-bottom: 0.2rem; }
.club-show-name { font-size: 1.05rem; }
.club-show-meta { color: var(--text-muted); font-size: 0.85rem; font-weight: 600; }
.club-show-judge { line-height: 1.6; }
.club-show-judge a { color: var(--accent-text); text-decoration: none; }
.club-show-judge a:hover { text-decoration: underline; }
.club-show-cc { color: var(--text-primary); }
.club-show p.club-show-venue { font-size: 0.9rem; margin-bottom: 0.2rem; }
.club-show p.club-show-organiser { align-items: center; color: var(--text-muted); display: flex; flex-wrap: wrap; font-size: 0.9rem; gap: 0.4rem; line-height: 1.4; margin-top: 0.35rem; }
.club-show-organiser a { color: inherit; }
.club-show { align-items: start; column-gap: 0.9rem; display: grid; grid-template-columns: 42px minmax(0, 1fr); }
.club-show-body { min-width: 0; }
.club-show-mark { margin-top: 0.1rem; overflow: hidden; }
.club-show-mark .action-icon { height: 22px; width: 22px; }
.club-show-mark img { background: #fff; height: 100%; object-fit: contain; width: 100%; }
@media (max-width: 600px) { .club-day-head { flex-direction: column; gap: 0.2rem; } }

/* Settings -> Breed clubs: Dimas's own logo address (SHOW-180). */
.club-admin-url { display: flex; gap: 0.5rem; }
.club-admin-url input { flex: 1 1 auto; min-width: 0; }

/* Settings -> Breed clubs: the manual picture behind one button, and the card as a drop zone (SHOW-180). */
.club-admin-manual { display: grid; flex: 1 1 100%; gap: 0.5rem; }
.club-admin-manual[hidden] { display: none; }
.club-admin-upload { align-items: center; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.club-admin-file { cursor: pointer; }
.club-admin-drop-hint { color: var(--text-muted); font-size: 0.8rem; }
.club-admin-card.is-drop { box-shadow: 0 0 0 2px var(--accent-primary); }

/* About the show: previous and next show under the cards (SHOW-186). */
.show-info-nav { margin-top: 1.5rem; }
.show-info-nav-row { display: grid; gap: 0.75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.show-info-nav-link { align-items: center; color: inherit; display: flex; gap: 0.75rem; margin-bottom: 0; padding: 1rem 1.25rem; text-decoration: none; }
.show-info-nav-link:hover { box-shadow: 0 0 0 1px var(--accent-primary), var(--shadow-premium); }
.show-info-nav-link.is-next { flex-direction: row-reverse; text-align: right; }
.show-info-nav-icon { color: var(--accent-text); display: inline-flex; flex: 0 0 auto; }
.show-info-nav-icon .action-icon { height: 28px; width: 28px; }
.show-info-nav-text { display: grid; gap: 0.15rem; min-width: 0; }
.show-info-nav-label { color: var(--text-secondary); font-size: 0.9rem; }
.show-info-nav-name { font-size: 1.1rem; font-weight: 700; overflow-wrap: anywhere; }
@media (max-width: 520px) { .show-info-nav-link { padding: 0.85rem 1rem; } .show-info-nav-name { font-size: 1rem; } }
.show-info-nav h2 { margin: 0 0 0.75rem; }

/* About the show: the dates in one block of two lines, right of the title, like a timetable day chip (Dimas, 2026-11-02). */
.show-info-title-row .show-info-date { margin-left: auto; }
.show-info-date { align-items: center; background: var(--accent-glow); border: 1px solid var(--accent-primary); border-radius: 10px; color: var(--bg-base); display: inline-flex; flex: 0 0 auto; flex-direction: column; line-height: 1.1; min-width: 64px; padding: 0.45rem 0.75rem; text-align: center; }
.show-info-date strong { color: #fff; font-size: 1.35rem; font-weight: 800; white-space: nowrap; }
.show-info-date span { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap; }
.schedule-heading > div:has(> .show-info-title-row) { flex: 1 1 auto; min-width: 0; width: 100%; }

/* About the show: each day's official show name under the intro (Dimas, 2026-11-02). */
.show-info-expos { display: grid; gap: 0.3rem; list-style: none; margin: 0.75rem 0 0; max-width: 46rem; padding: 0; }
.show-info-expos li { column-gap: 0.6rem; display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); line-height: 1.4; }
.show-info-expo-date { color: var(--text-secondary); font-weight: 700; white-space: nowrap; }
/* A day with a timetable opens it: the accent and an underline say it is a link (Dimas, 2026-11-02). */
a.show-info-expo-date.is-link { color: var(--accent-text); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
a.show-info-expo-date.is-link:hover { text-decoration-thickness: 2px; }
.show-info-expo-name { color: var(--text-primary); }
