/* Self-hosted Noto Sans subset (Greek + Latin). Unlike Arial/Liberation, it
   carries GPOS mark-anchor data, so the combining caron (U+030C) used in
   Cypriot text (ζ̌, σ̌, …) sits centred above the letter instead of drifting
   to its right. Self-hosted (not Google Fonts) on purpose: Google splits Greek
   letters and combining marks into separate subset files, which breaks the
   cross-glyph mark attachment. */
@font-face {
    font-family: 'Noto Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/notosans-greek.woff2') format('woff2');
    unicode-range: U+0000-024F, U+0300-036F, U+0370-03FF, U+1F00-1FFF, U+2000-206F, U+20AC, U+2122, U+2212, U+25CC;
}
@font-face {
    font-family: 'Noto Sans';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/notosans-greek-bold.woff2') format('woff2');
    unicode-range: U+0000-024F, U+0300-036F, U+0370-03FF, U+1F00-1FFF, U+2000-206F, U+20AC, U+2122, U+2212, U+25CC;
}

/* Self-hosted GFS Didot. The Google-hosted woff2 (gfsdidot v18) ships glyf entries
   whose stored bounding boxes don't match their outlines, so Firefox logs a
   "Glyph bbox was incorrect; adjusting" warning for every affected glyph on each
   page load. This copy is the same font with the bounding boxes recomputed, so it
   loads cleanly. */
@font-face {
    font-family: 'GFS Didot';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/gfs-didot.woff2') format('woff2');
}

/* ── Stratum: the token layer ───────────────────────────────────────────────
   Every colour, face and rule on the site resolves through one of these. Change
   a value here and it changes everywhere; that is the whole point, and it is
   what makes the dark palette below cost twenty lines instead of a rewrite.

   --plate is #E5D2B1 exactly. That is the ground baked into the taxa
   illustrations, so artwork sits on a plate with no visible seam.

   There is deliberately no brand accent. --period is the ICS colour of whatever
   the page is about (jsondata/ics_periods.json), set per page by the generator,
   so an accent always means "when" and never anything else. --accent is the
   fallback for pages that are not about a moment in time.                     */
:root {
    /* Tells the browser which way the page is lit, so form controls, scrollbars and
       the like follow the palette instead of the device. Without it Chrome on a dark
       Android will also apply its own auto-darkening on top of ours. */
    color-scheme: light;

    --ground:      #efe4cc;
    --ground-2:    #e8dabc;
    --ground-3:    #f5eeda;
    --plate:       #e5d2b1;

    --ink:         #221b12;
    --ink-2:       #5f4f3b;
    --ink-3:       #8d795e;
    --on-dark:     #f2e8d4;

    --rule:        rgba(34, 27, 18, 0.16);
    --rule-2:      rgba(34, 27, 18, 0.34);

    --accent:      #8b5a2b;
    /* The ink for anything printed on the accent. It is a token because the accent
       turns over with the palette: dark brown here, lamplit gold in the dark one,
       so a single light colour cannot read on both. */
    --on-accent:   #f7f0dd;
    --period:      var(--accent);
    --danger:      #b04540;

    --lift:   0 1px 2px rgba(34, 27, 18, 0.10), 0 10px 28px -14px rgba(34, 27, 18, 0.42);
    --lift-2: 0 2px 4px rgba(34, 27, 18, 0.12), 0 18px 40px -18px rgba(34, 27, 18, 0.55);

    --display: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
    --body:    'Noto Sans', system-ui, -apple-system, sans-serif;
    /* The data voice: catalogue counts, ages, formations, dates. Anything that is
       a measurement rather than a sentence is set in this, which is what keeps
       parchment and Didot from reading as a wedding invitation. */
    --data:    ui-monospace, 'DejaVu Sans Mono', 'SF Mono', Menlo, monospace;

    --ease: cubic-bezier(0.22, 1, 0.36, 1);

    /* Greek drops its accents in capitals — ΓΕΩΛΟΓΙΚΟΣ, not ΓΕΩΛΟΓΙΚΌΣ — and
       browsers implement that when uppercasing, but only for `el`. Ancient Greek
       and Cypriot are tagged `grc` and `cyp`, get the generic Unicode casing
       instead, and come out accented. Rather than lie about the language of the
       text, those two keep their natural case: the monospaced face, the size and
       the letterspacing carry the data voice without capitals. */
    --caps: uppercase;
}

:root:lang(grc),
:root:lang(cyp) {
    --caps: none;
    --caps-tracking: 0.06em;
}

/* Cypriot is written with combining carons — ζ̌, σ̌, τζ̌αι, Πλειότζ̌αινον. Putting a
   mark over a letter is GPOS data held inside a font, and it does not work across
   two of them: GFS Didot has no caron at all, so the browser borrows one from
   wherever it can and lands it to the right of the letter instead of above it.
   The monospaced data face has the same gap. A Cypriot page therefore sets every
   voice to the one face that carries the anchors, which is why Noto Sans is
   self-hosted here in the first place. */
:root:lang(cyp) {
    --display: 'Noto Sans', system-ui, -apple-system, sans-serif;
    --data: 'Noto Sans', ui-monospace, 'DejaVu Sans Mono', monospace;
}

/* The dark palette is a lamplit reading room, not an inverted document: warm
   near-black ground, parchment ink, and the plates left warm so illustrations
   and specimen photographs are never tinted by the theme.

   It is opt-in. The site does not follow prefers-color-scheme, because the
   parchment ground is the design rather than a default that a dark-mode reader
   should be spared; a reader who wants the dark one asks for it from the menu
   and the choice is remembered. */
:root[data-theme="dark"] {
    color-scheme: dark;

    --ground:   #14100b;
    --ground-2: #221c14;
    --ground-3: #2e261b;
    --plate:    #e5d2b1;

    --ink:      #f4ead6;
    --ink-2:    #cbb896;
    --ink-3:    #9c876c;
    --on-dark:  #f4ead6;

    --rule:     rgba(244, 234, 214, 0.13);
    --rule-2:   rgba(244, 234, 214, 0.28);

    --accent:    #e0a95f;
    --on-accent: #241d13;

    --lift:   0 1px 2px rgba(0, 0, 0, 0.55), 0 10px 28px -14px rgba(0, 0, 0, 0.85);
    --lift-2: 0 2px 4px rgba(0, 0, 0, 0.6),  0 18px 40px -18px rgba(0, 0, 0, 0.95);
}

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

body {
    font-family: var(--body);
    margin: 0;
    padding: 0;
    background-color: var(--ground);
    color: var(--ink);
    font-size: 16px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;

    min-height: 100vh;
    /* Flex column so .main-section-wrapper (flex: 1) grows to fill the viewport and
       pushes #footer-container to the bottom on short pages (e.g. the quiz). Without
       display:flex the flex-direction/flex:1 below are inert and the footer floats up. */
    display: flex;
    flex-direction: column;
}

html, body {
    height: 100%;
}

#paste-point {
  /* Fill the flex-column body so the footer sits at the bottom, but never shrink below
     the injected content: with the default flex-shrink:1 this box would collapse to its
     min-height while a long journal article overflows past it, dropping the footer
     mid-page. flex-shrink:0 keeps it as tall as its content. */
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

/* The header was a dark grey slab. It is now part of the page: parchment,
   separated by a hairline rather than a block of colour, so nothing competes
   with the specimens. */
header {
    background-color: var(--ground-2);
    color: var(--ink);
    padding: 0;
    text-align: left;
    border-bottom: 1px solid var(--rule-2);
}

nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

nav li {
    display: inline;
    margin: 0 10px;
}

nav a {
    color: inherit;
    text-decoration: none;
}

.lang-button {
    color: inherit;
    text-decoration: none;
    margin: 0 10px;
}

main {
    padding: 20px;
}

/* ── Typography ─────────────────────────────────────────────────────────────
   Display face for names and headings, body face for prose, monospace for data.
   Applied here once rather than repeated per component. */
h1, h2, h3, h4,
.journal-entry-title, .journal-index-title {
    font-family: var(--display);
    font-weight: 400;
    letter-spacing: -0.005em;
    line-height: 1.12;
    color: var(--ink);
}

/* Running prose wants a measure. Anything wider than this is tiring to read and
   is the single commonest reason a text-heavy page feels amateur. */
.description-text p,
.etymology-text p,
.journal-entry-content p {
    max-width: 66ch;
}

a { color: inherit; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* The data voice. Used by the generator for ages, formations, counts and dates. */
.data {
    font-family: var(--data);
    font-size: 11px;
    line-height: 1.5;
    letter-spacing: 0.11em;
    text-transform: var(--caps);
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}

.main-section-wrapper {
  flex: 1;
}

/* ── The homepage band ──────────────────────────────────────────────────────
   Flush 80px cells: most hold one of six earth tints over --plate, the rest hold
   specimen photographs that scripts/mosaic.js fades in and out. The tints are
   listed rather than mixed at runtime. */
:root {
    --m-1: #caae89;
    --m-2: #d3b68f;
    --m-3: #c2ac8c;
    --m-4: #dbc39c;
    --m-5: #bdab8e;
    --m-6: #cbb798;
}

/* The same six earths at lamplight: the band opens the dark page as well, and a
   strip of noon sand above a night ground read as a window left open. Same hues
   and the same spread between them, so the mosaic keeps its texture. */
:root[data-theme="dark"] {
    --m-1: #3a2f22;
    --m-2: #403425;
    --m-3: #362d21;
    --m-4: #45392a;
    --m-5: #332b20;
    --m-6: #3b3126;
}

/* Full-bleed: #hero sits outside .main-section-wrapper in the template rather
   than escaping it with viewport units, which do not subtract the scrollbar. */
#hero {
    position: relative;
}

#hero-grid {
    display: grid;
    /* Tiles shrink with the window instead of holding 80px, which on a phone gave
       four across. The 120px ceiling is where the 300x169 thumbnails start being
       upscaled by the 1.25 zoom. */
    --m-cell: clamp(48px, 5.5vw, 120px);
    grid-template-columns: repeat(auto-fill, minmax(var(--m-cell), 1fr));
    grid-auto-rows: var(--m-cell);
    height: 34vh;
    overflow: hidden;
    /* A window taller than the prerendered rows reach shows this rather than the page. */
    background-color: var(--m-3);
}

.m-cell {
    position: relative;
    overflow: hidden;
    background-color: var(--m-4);
}

.m-t1 { background-color: var(--m-1); }
.m-t2 { background-color: var(--m-2); }
.m-t3 { background-color: var(--m-3); }
.m-t4 { background-color: var(--m-4); }
.m-t5 { background-color: var(--m-5); }
.m-t6 { background-color: var(--m-6); }

/* The global img rule centres images and gives them a margin; in a cell the image
   is the cell. scale() crops further in, past the edges of the rock. */
.m-cell img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    object-fit: cover;
    transform: scale(1.25);
    transition: opacity 2250ms var(--ease);
}

/* A photograph is lit the same whatever the page around it, which on the dark
   ground leaves the occupied cells glaring. Held back enough to sit in the band
   rather than punch through it, and no further: they are still the specimens. */
:root[data-theme="dark"] .m-cell img {
    filter: brightness(0.78);
}

/* Set by mosaic.js on an image arriving or leaving; the prerendered frame carries
   neither and is opaque from the first paint. */
.m-cell img.m-in,
.m-cell img.m-out { opacity: 0; }

#hero-plate {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* Sized to its contents, so the padding pushes the plate's edges outward
       instead of narrowing the text inside a box of fixed width. */
    width: fit-content;
    max-width: calc(100% - 2rem);
    padding: 16px 44px;
    background-color: var(--ground);
    border: 1px solid var(--rule);
    border-radius: 13px;
    box-shadow: var(--lift);
    text-align: center;
}

#hero-title {
    margin: 0;
    font-size: clamp(2rem, 6vw, 3.4rem);
    color: var(--ink);
}

/* The data voice, as on a specimen label. --caps leaves grc and cyp in their
   natural case, which is why the tracking is set here rather than the capitals. */
#hero-tagline {
    margin: 0.5em 0 0;
    font-family: var(--data);
    font-size: clamp(9px, 1.5vw, 11px);
    letter-spacing: 0.14em;
    line-height: 1.5;
    text-transform: var(--caps);
    color: var(--ink-3);
}

@media (max-width: 560px) {
    #hero-plate { padding: 14px 24px; }
}

/* A reader who asked for less motion gets the opening frame and nothing further;
   mosaic.js checks the same query before it schedules anything. */
@media (prefers-reduced-motion: reduce) {
    .m-cell img { transition: none; }
}

/* The tally. Rules rather than chips: five figures sharing one baseline read as
   a record, where five rounded pills read as a dashboard. */
#stats-panel {
    display: grid;
    /* One column per figure in the markup, so adding or dropping one is a change
       to the HTML alone. */
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    /* The separation lives in the gap, not in a left padding, so every figure
       starts flush with its own column. Padding the cells instead meant the
       first one had to be given none of it — otherwise it sat indented from the
       text above — and it ended up seventeen pixels out of step with the other
       four. */
    column-gap: 26px;
    margin: 1.5rem 0 2rem;
    border-top: 1px solid var(--rule-2);
    border-bottom: 1px solid var(--rule-2);
}

#stats-panel .stat {
    position: relative;
    text-align: left;
    padding: 14px 0 13px;
    min-width: 0;
}

/* Four of the five figures are a link or a button rather than a cell, so they are
   stripped back to the cell they replace and take their layout from the rules
   above and below like any other. */
/* No display here: in the grid these are grid items and are blockified anyway, and
   on a phone the panel's own rule turns every cell into a flex row. Setting one
   would outrank that rule and undo the phone layout. */
#stats-panel a.stat,
#stats-panel button.stat {
    width: 100%;
    /* appearance first: without it Chrome on Android keeps drawing the native
       button around the figure and laying its content out as one, whatever
       background, border and text-align say. */
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    background: none;
    border: 0;
    border-radius: 0;
    font: inherit;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

/* A dotted rule under the label, not an underlined link: it says the figure leads
   somewhere without turning the record into a row of buttons, and unlike a hover
   it is there on a phone as well. The fifth figure has no rule, which is how the
   panel says that one is only a count. */
#stats-panel a.stat .stat-label,
#stats-panel button.stat .stat-label {
    text-decoration: underline dotted var(--rule-2);
    text-underline-offset: 4px;
}

#stats-panel a.stat:hover .stat-number,
#stats-panel button.stat:hover .stat-number,
#stats-panel a.stat:focus-visible .stat-number,
#stats-panel button.stat:focus-visible .stat-number {
    color: var(--accent);
}

#stats-panel a.stat:hover .stat-label,
#stats-panel button.stat:hover .stat-label,
#stats-panel a.stat:focus-visible .stat-label,
#stats-panel button.stat:focus-visible .stat-label {
    color: var(--ink-2);
    text-decoration-color: var(--accent);
}

/* The divider is drawn in the middle of the gap rather than on the cell's own
   edge, where it would hug the figure to its left and leave the whole 26px of
   air on the other side. It belongs to the figure on its right, not the one on
   its left. */
#stats-panel .stat + .stat::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -13px;
    border-left: 1px solid var(--rule);
}

#stats-panel .stat-number {
    display: block;
    font-family: var(--display);
    font-size: clamp(1.6rem, 3.2vw, 2.4rem);
    font-weight: 400;
    line-height: 1;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

#stats-panel .stat-label {
    display: block;
    margin-top: 7px;
    font-family: var(--data);
    font-size: 10px;
    letter-spacing: 0.1em;
    text-transform: var(--caps);
    color: var(--ink-3);
}

/* Two columns on a narrow screen draw a table without side edges, and with five
   figures the divider between the columns stops halfway down, at the row the
   fifth has to itself: every cell reads as a box left open. One figure per line
   instead — label, then its count — with a rule under each. A list has no boxes
   to leave open. */
@media (max-width: 700px) {
    #stats-panel {
        display: block;
    }

    #stats-panel .stat {
        display: flex;
        flex-direction: row-reverse;
        justify-content: space-between;
        align-items: baseline;
        gap: 1rem;
        padding: 11px 0 10px;
    }

    /* The rule goes above each line rather than below it, so the panel's own
       bottom border closes the list whichever line turns out to be the last
       one drawn. */
    #stats-panel .stat + .stat {
        border-top: 1px solid var(--rule);
    }

    /* No columns here, so no divider between them. Matches the specificity of
       the rule that sets it, or it does not win. */
    #stats-panel .stat + .stat::before {
        content: none;
    }

    #stats-panel .stat-number {
        font-size: 1.5rem;
    }

    #stats-panel .stat-label {
        margin-top: 0;
    }
}

.taxon-title-wrap {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.taxon-title-wrap h2 {
    margin: 0;
}

.taxon-phylopic {
    height: 2em;
    width: 2em;
    object-fit: contain;
    flex-shrink: 0;
}

.lightbox-meta {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-top: 0.6rem;
    padding-top: 0.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.2);
    font-size: 0.9em;
    color: #ccc;
}

.lightbox-meta a {
    color: #e8d4a9;
    text-decoration: none;
}

.lightbox-meta a:hover {
    text-decoration: underline;
}


/* Sections used to each be a white card with a shadow, which turned every page
   into a stack of floating boxes. They are now just intervals in one continuous
   sheet; the components that genuinely are objects (plates, cards) carry their
   own edges. */
section {
    margin-bottom: 0;
    background-color: transparent;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
}

main > section,
main > div > section {
    margin-bottom: clamp(38px, 6vw, 72px);
}

img {
    max-width: 100%;
    height: auto;
    display: block; /* Οι εικόνες να καταλαμβάνουν όλο το πλάτος */
    margin: 10px auto; /* Κεντράρισμα εικόνων */
}

footer {
    background-color: transparent;
    color: var(--ink-3);
    padding: 24px 20px 48px;
    text-align: center;
    border-top: 1px solid var(--rule-2);
    font-family: var(--data);
    font-size: 11px;
    letter-spacing: 0.09em;
    text-transform: var(--caps);
}

footer p { margin: 0; }

.footer-link {
    text-decoration: none;
    color: var(--ink-3);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: color 0.2s;
}

.footer-link:hover { color: var(--ink); }

/* An inline-flex box whose items are all centre-aligned has no baseline of its
   own, so the browser synthesises one from its bottom edge: the 18px icon set
   the box's height and the label rode six pixels above the line everything
   either side of it sits on. Aligning on the baseline lets the label supply the
   box's baseline, and the icon centres against it. */
.repo-link {
    margin-left: 12px;
    align-items: baseline;
}

.github-icon {
    width: 18px;
    height: 18px;
    align-self: center;
}

/* Hide text on small screens (icon only) */
.repo-text {
    display: none;
}

/* Show localized text on wider screens */
@media (min-width: 600px) {
    .repo-text {
        display: inline;
    }
}

.footer-separator {
    margin: 0 10px;
    opacity: 0.6;
    user-select: none;
}

@media (max-width: 600px) {
    .footer-separator {
        margin: 0 6px;
    }
}

/* Πρόσθεσε τις CSS ιδιότητες που θες */
.gallery {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}

.gallery a {
    margin: 5px;
}

.gallery img {
    width: 200px; /* Μέγεθος μικρογραφιών */
    height: 100%;
    border: 1px solid var(--rule);
}

#search-container {
    position: relative;
    float: right;
}

/* An input keeps the browser's own colours unless it is given some, which left a
   white box with black text sitting in the dark header. */
#search-input {
    background: var(--ground-3);
    color: var(--ink);
    border: 1px solid var(--rule-2);
    border-radius: 0;
    padding: 5px 8px;
    font-family: var(--body);
    font-size: 14px;
}

#search-input::placeholder {
    color: var(--ink-3);
}
  
#search-results {
position: absolute;
top: calc(100% + 4px);
left: 0;
width: 100%;
background-color: var(--ground-3);
border: 1px solid var(--rule-2);
box-shadow: var(--lift);
list-style: none;
padding: 0;
margin: 0;
z-index: 60;
display: none; /* Κρύβουμε τα αποτελέσματα αρχικά */
}

#search-results li {
padding: 7px 10px;
cursor: pointer;
color: var(--ink);
font-size: 14px;
display: flex;
align-items: center;
gap: 0.5rem;
}

#search-results li .search-result-icon,
#search-results li .search-result-icon-placeholder {
width: 18px;
height: 18px;
flex-shrink: 0;
object-fit: contain;
}

/* No disc under these, so on the dark palette they are inverted, like the story
   silhouette. */
:root[data-theme="dark"] #search-results li .search-result-icon {
    filter: invert(1);
}

#search-results li.highlighted {
background-color: var(--ground-2);
}

.container {
display: flex;
align-items: center;
justify-content: center;
}

.foo-container {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: 1rem;
}

.description-text {
    display: flex;
    flex-direction: column;
    justify-content: stretch;
}

/* The kingdom tiles. The illustrations are the best asset the site owns, so
   they are given a full plate each instead of a centred half-width thumbnail
   floating in whitespace. */
.tax-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 18px;
    justify-content: initial;
}

.tax-container a {
    text-align: left;
    text-decoration: none;
    background: var(--ground-2);
    border: 1px solid var(--rule-2);
    box-shadow: var(--lift);
    overflow: hidden;
    transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

.tax-container a:hover {
    transform: translateY(-4px);
    box-shadow: var(--lift-2);
}

.tax-container .tax-subcontainer {
    display: block;
    padding: 0;
    height: auto;
}

.tax-container .tax-thumbnail-image {
    width: 100%;
    margin: 0;
    background: var(--plate);
    border: 0;
    border-bottom: 1px solid var(--rule);
    box-shadow: none;
}

.tax-container h3 {
    font-size: 1.3rem;
    margin: 12px 0.8rem;
}

/* The wrapper is still used as a plain column elsewhere (the homepage section
   that holds the heading above the grid), so its flex behaviour stays. */
.tax-subcontainer {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: stretch;
    height: 100%;
    padding: 0;
    box-sizing: border-box;
}

.tax-page-image {
max-height: 400px;
height: 100%;
width: auto;
object-fit: contain;
max-width: 100%;
}

.tax-thumbnail-image {
width: 50%; /* Μικρό μέγεθος εικόνας */
}

.header-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    max-width: 100%;
}

header div > * {
    max-width: 100%;
}

/* The old blanket `header div { padding: 10px 20px }` also hit #search-container
   and .lang-dropdown, padding them individually and inflating the bar to 85px.
   .header-top and .breadcrumbs each set their own layout. */

@media (max-width: 600px) {
    #search-container,
    #navpath-section,
    .container {
        width: 100%;
        text-align: center;
    }
}

.main-section-wrapper {
    max-width: 1000px; /* or 1200px for wider layout */
    /* The auto margins that centre this box also make it a shrink-to-fit flex item,
       so a page with narrow content sat at its content width rather than the column
       width — which put the locality hero's title, set against the column, out of
       line with the text under it. */
    width: 100%;
    margin: 0 auto; /* centers the wrapper horizontally */
    padding: 20px; /* optional: adds space inside the wrapper */
}

.header-top {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: nowrap;
    padding: 10px 20px;
    background-color: transparent;
    color: var(--ink);
}

/* Search sits on the right, everything else hugs the left */
.header-top #search-container {
    margin-left: auto;
    padding: 0;
}

/* 3-bar hamburger */
.sidebar-toggle {
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.hamburger-bars,
.hamburger-bars::before,
.hamburger-bars::after {
    display: block;
    width: 26px;
    height: 3px;
    border-radius: 2px;
    background: var(--ink);
    transition: transform 0.25s ease, opacity 0.25s ease;
}

.hamburger-bars {
    position: relative;
}

.hamburger-bars::before,
.hamburger-bars::after {
    content: '';
    position: absolute;
    left: 0;
}

.hamburger-bars::before { top: -8px; }
.hamburger-bars::after { top: 8px; }

/* Small home icon button in the header */
.home-icon-btn {
    color: var(--ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    padding: 4px;
}

.home-icon-btn svg {
    width: 26px;
    height: 26px;
    display: block;
}

.home-icon-btn:hover { color: var(--accent); }

.lang-dropdown select {
    padding: 5px;
    font-size: 14px;
    border-radius: 0;
    border: 1px solid var(--rule-2);
    background-color: var(--ground-3);
    color: var(--ink);
}

/* The trail is the reader's position in the taxonomy, so the ancestors are
   quiet and the page they are actually on is not.

   The underline is ink, not --period. A taxon is not a moment in time: most
   span several periods, and even where every specimen happens to come from one,
   colouring the taxonomic trail by the age of the rocks the specimens were
   found in would be saying something untrue. --period stays on the things that
   really are about when: the locality spine and the deep-time bracket. */
.breadcrumbs {
    /* The generator knows whether a page has a trail and writes an inline
       display:none on the ones that don't, so this no longer waits for JavaScript. */
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    padding: 9px 20px 10px;
    background-color: transparent;
    border-top: 1px solid var(--rule);
    color: var(--ink-2);
    gap: 4px 2px;
}

.crumb {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border-radius: 0;
    background: transparent;
    color: var(--ink-2);
    text-decoration: none;
    font-size: 0.88rem;
    line-height: 1.3;
    transition: color 0.15s ease, background 0.15s ease;
}

a.crumb:hover {
    background: var(--ground-3);
    color: var(--ink);
}

.crumb.current {
    background: transparent;
    color: var(--ink);
    font-weight: 700;
    border-bottom: 2px solid var(--ink);
    padding-bottom: 1px;
}

.crumb-icon {
    width: 20px;
    height: 20px;
    object-fit: contain;
    display: inline-block;
    margin: 0;
    /* Same reasoning as .node-icon: a black silhouette needs a light disc in
       both palettes. */
    background: var(--plate);
    border: 1px solid var(--rule);
    border-radius: 50%;
    padding: 1px;
    flex-shrink: 0;
}

/* The story silhouette sits directly on the page rather than on a disc, so on
   the dark palette it is inverted instead. */
:root[data-theme="dark"] .story-phylopic img {
    filter: invert(1);
}

.crumb-sep {
    color: var(--ink-3);
    font-size: 1rem;
    padding: 0 1px;
    user-select: none;
}

@media (max-width: 600px) {
    .header-top {
        flex-wrap: wrap;
        align-items: center;
        gap: 0.5rem;
        padding: 8px 10px;
    }

    /* Search drops onto its own full-width row below the controls */
    .header-top #search-container {
        flex: 1 1 100%;
        order: 3;
        margin-left: 0;
        text-align: center;
    }

    #search-input {
        width: 100%;
        max-width: none;
        box-sizing: border-box;
    }

    .breadcrumbs {
        flex-wrap: wrap;
        justify-content: center;
        padding: 6px 10px;
    }
}

.lang-dropdown {
  position: relative;
  display: inline-block;
}

.header-top .lang-dropdown {
  flex: 0 0 auto;
}

#language-toggle {
  background: transparent;
  color: var(--ink-2);
  padding: 4px 8px;
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: var(--caps);
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: color 0.15s ease, border-color 0.15s ease;
}

#language-toggle:hover {
  color: var(--ink);
  border-color: var(--rule-2);
}

#language-toggle img {
  vertical-align: middle;
}

#language-menu {
  display: none;
  position: absolute;
  right: 0;
  /* Sized to its longest entry, not to the button above it. The blanket
     `header div > *` rule left over from the old header puts max-width: 100% on
     everything in there, which clamped this menu to the width of the toggle —
     fine until "Ἑλληνική ἀρχαία" turned out to be half again as wide as
     "English" and spilled out of its own box. Anchored right, so it grows
     leftwards and cannot run off the screen. */
  width: max-content;
  min-width: 100%;
  max-width: min(86vw, 320px);
  background-color: var(--ground-3);
  border: 1px solid var(--rule-2);
  box-shadow: var(--lift);
  z-index: 70;
  border-radius: 0;
  margin-top: 5px;
  padding: 0;
  list-style: none;
}

#language-menu li {
  padding: 9px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--ink);
  white-space: nowrap;
}

#language-menu li:hover {
  background-color: var(--ground-2);
}

/* The menu comes in two shapes. On a per-language page each entry is a real link to
   that language's URL, so the row's padding and the flex layout belong to the anchor;
   on the gallery and journal shells language.js still builds plain list items. */
#language-menu li.lang-option {
  padding: 0;
}

#language-menu li.lang-option > a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  width: 100%;
  color: inherit;
  text-decoration: none;
}

#language-menu li img {
  width: 20px;
  height: 20px;
  object-fit: contain;
  vertical-align: middle;
  /* Overrides the site-wide `img { display: block; margin: 10px auto }`, which would
     otherwise drop the flag onto its own line inside the anchor. */
  display: inline-block;
  margin: 0;
}

.sidebar {
  position: fixed;
  left: 0;
  width: 50%;
  width: auto;
  max-width: 80vw; /* or 80% if using in layout, but vw better for fixed sidebar */
  overflow-y: auto;
  background: var(--ground-3);
  color: var(--ink);
  border-right: 1px solid var(--rule-2);
  box-shadow: var(--lift-2);
  transition: transform 0.3s var(--ease);
  z-index: 100;
  font-size: 0.85rem;
  line-height: 1.2;
  margin: 0;
  padding-bottom: 0.5em;
  padding-right: 2em;
  overflow-x: hidden;
  display: none;
}

.sidebar a {
    color: var(--ink);
    text-decoration: none;
}

/* ---- Drawer sections ---- */
.drawer-nav {
  display: flex;
  flex-direction: column;
  padding: 0.8em 0.6em 0.5em 0.9em;
  border-bottom: 1px solid var(--rule-2);
}

.drawer-nav a {
  color: var(--ink);
  text-decoration: none;
  padding: 0.5em 0.5em;
  border-radius: 0;
  font-family: var(--data);
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: var(--caps);
}

.drawer-nav a:hover {
  background: var(--ground-2);
}

.drawer-tree {
  /* The row's measure. Icon, label line box, toggle offset and the height the
     connectors meet at are all derived from this one value. */
  --node-icon: 22px;
  /* Air above and below each row. The junction the connectors meet at is
     measured from it, so the two cannot drift apart. */
  --row-pad: 0.34em;
  padding: 0.7em 0 0.5em 0.5em;
}

.drawer-tree h3 {
  margin: 0 0 0.7em 0.4em;
  font-family: var(--data);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.11em;
  text-transform: var(--caps);
  color: var(--ink-3);
}

.sidebar ul {
  list-style: none;
  margin: 0;
  /* No padding: a child list starts exactly at its parent's toggle, which is
     what puts the rail below under the control it descends from. */
  padding-left: 0;
  position: relative;
}

.sidebar li {
  position: relative;
  padding-left: 1.2em; /* the channel the connectors are drawn in */
  margin: 0.05em 0;
}

/* ---- Connectors ------------------------------------------------------------
   The drawer is a classification, so the lines have to say what hangs off what.
   Each child draws its own rail and its own elbow: the rail descends from the
   parent's toggle through every sibling and stops at the last of them, so a
   group visibly closes rather than trailing off.

   Previously the rail was one line down the whole list and the elbow was drawn
   from the list edge, crossing the rail and stopping short of the node. Every
   row was marked with a small ✛ floating in the indent, connected to nothing at
   either end, and the only way to read the depth was to count it. */

/* --guide is the centre of the parent's toggle, measured from this row's own
   left edge; --junction is the centre of this row's icon, which is where the
   elbow has to arrive and where a closing rail has to stop. */
.sidebar li {
  --guide: 0.55em;
  --junction: calc(var(--row-pad) + var(--node-icon) / 2);
}

/* The rail, carrying on past this row to the siblings below it. */
.sidebar li::after {
  content: '';
  position: absolute;
  left: var(--guide);
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--rule-2);
}

/* The last of a group ends the rail at its own junction, closing the ⌐ into an
   └ so the group has a visible bottom. */
.sidebar li:last-child::after {
  bottom: auto;
  height: var(--junction);
}

/* The elbow, run all the way to the toggle instead of stopping in mid-air. */
.sidebar li::before {
  content: '';
  position: absolute;
  top: var(--junction);
  left: var(--guide);
  width: calc(1.2em - var(--guide));
  height: 1px;
  background: var(--rule-2);
}

/* The kingdoms are roots. There is no parent above them to hang them from, so
   they get neither rail nor elbow. */
#tree-container > ul > li {
  padding-left: 0;
}

#tree-container > ul > li::before,
#tree-container > ul > li::after {
  content: none;
}

.sidebar.collapsed {
  transform: translateX(-100%);
}

/* The toggle and the link, on a row of their own and aligned to its top, so the
   icon stays beside the first line of a label that wraps rather than sliding to
   the middle of two — which is where the connectors expect to meet it. */
.tree-row {
  display: flex;
  align-items: flex-start;
  padding: var(--row-pad) 0;
}

.tree-node {
  display: flex;
  align-items: flex-start;
  gap: 0.5em;
  min-width: 0;
  color: var(--ink);
  font-family: var(--body);
  font-size: 1em;
  text-decoration: none;
}

.tree-node:hover {
  color: var(--accent);
}

.tree-node:hover .node-label {
  text-decoration: underline;
}

/* circular phylopic icon node. Its size is the row's measure: the label's line
   box and the toggle's offset are both derived from it, so the icon, the glyph
   and the connector all meet on one line. */
.node-icon {
  width: var(--node-icon);
  height: var(--node-icon);
  flex: 0 0 var(--node-icon);
  border-radius: 50%;
  /* PhyloPic silhouettes are solid black, so their disc stays parchment in both
     palettes; inverting the ground instead would erase the shape. */
  background-color: var(--plate);
  background-size: 72%;
  background-repeat: no-repeat;
  background-position: center;
  border: 1px solid var(--rule-2);
  box-sizing: border-box;
}

.node-icon.no-icon {
  background-color: var(--ground-2);
  border-color: var(--rule);
}

/* One line of label is exactly one icon tall, so a first line always centres on
   its icon and a second line falls clear below it. */
.node-label {
  line-height: var(--node-icon);
}

.node-count {
  line-height: var(--node-icon);
  font-family: var(--data);
  font-size: 0.72em;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  white-space: nowrap;
}

.overlay {
  position: fixed;
  left: 60%;
  width: 100%;
  background: rgba(0, 0, 0, 0);
  z-index: 800;
}

.overlay.hidden {
  display: none;
}

.tree-toggle,
.tree-toggle-spacer {
  width: 1.1em;
  height: 1.1em;
  flex: 0 0 1.1em;
  box-sizing: border-box;
  /* Centred on the icon beside it rather than on the row, which is taller
     whenever the label wraps. */
  margin-top: calc((var(--node-icon) - 1.1em) / 2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* button reset + look. The font is inherited so that the button's 1.1em is the
   same 1.1em the connectors are positioned in — a button left on the browser's
   own font-size is a fraction narrower, and the rail then misses its centre. */
.tree-toggle {
  background: transparent;
  border: 1px solid var(--rule-2);
  border-radius: 3px;
  font: inherit;
  color: var(--ink-3);
  cursor: pointer;
  padding: 0;
  line-height: 1;
}

/* plus/minus glyphs */
.tree-toggle::before {
  content: "-"; 
  font-size: 0.95em;
}

.tree-item.is-collapsed > .tree-row > .tree-toggle::before {
  content: "+";
}

/* animated expand/collapse of children */
.tree-children-wrap {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.25s ease;
}

.tree-children-wrap > ul.tree-children {
  overflow: hidden;
  min-height: 0;
}

.tree-item.is-collapsed > .tree-children-wrap {
  grid-template-rows: 0fr;
}

.tree-toggle:hover {
  border-color: var(--ink-3);
  color: var(--ink);
}


/* ── Specimen plate ─────────────────────────────────────────────────────────
   Every photograph in this collection is a specimen on a table beside a ruler.
   Enlarged and full-bleed they look like snapshots; framed at a consistent size
   in a catalogue grid they look like what they are — the record of a find, with
   the ruler doing the job it was put there to do. So: one fixed window per
   specimen, no collage, and the number of photographs stated rather than
   crammed into the frame. */
.sample-box {
  width: 100%;
  height: auto;
  max-height: none;
  max-width: none;
  aspect-ratio: auto;
  position: relative;
  cursor: pointer;
  overflow: visible;
  margin: 0;
  background: var(--plate);
  border: 1px solid var(--rule-2);
  box-shadow: var(--lift);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

.sample-box:hover {
  transform: translateY(-3px);
  box-shadow: var(--lift-2);
}

.sample-frame {
  display: block;
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #cbbb9d;
}

.sample-frame .image-single,
.sample-frame .image-single img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  object-fit: cover;
  display: block;
}

/* Motion09 (D): the second view cross-fades in on hover. Specimens with a
   single photograph have no second layer and simply do nothing, which is not
   noticeable — the fade reads as the specimen being turned over, not as a
   control that some cards are missing. */
.sample-frame .image-single-alt {
  opacity: 0;
  transition: opacity 0.45s ease;
}

.sample-box:hover .sample-frame .image-single-alt { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .sample-frame .image-single-alt { transition: none; }
}

/* How many photographs this specimen has. */
.sample-count {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px;
  background: rgba(24, 19, 12, 0.72);
  color: var(--on-dark);
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: 0.06em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.icon-camera {
  width: 12px;
  height: 12px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  flex-shrink: 0;
}

/* A specimen mark for counts of specimens (as opposed to photographs). Emoji
   were used here before, which meant the row rendered differently on every
   operating system and not at all on some. */
/* "Purchased" badge shown on a thumbnail before the lightbox is opened.
   Pinned top-left so it never collides with the bottom-right "+N" overlay. */
.purchased-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  max-width: calc(100% - 12px);
  padding: 3px 8px 3px 6px;
  background: rgba(0, 0, 0, 0.6);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  pointer-events: none; /* keep clicks on the thumbnail opening the lightbox */
}

.purchased-badge-icon {
  width: 0.95em;
  height: 0.95em;
  fill: #e8d4a9; /* site gold accent */
  flex-shrink: 0;
}

.purchased-badge-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Provenance detail under the "🛒 Purchased" row inside the lightbox. */
.lightbox-acquisition-detail {
  font-size: 0.85em;
  color: #b9b9b9;
  font-style: italic;
  padding-left: 1.5em; /* align under the 🛒 label text */
}

.side-by-side-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
  max-width: 1000px; /* Set maximum width */
  margin: 0 auto; /* Optional: center the container */
}

@media (max-width: 600px) {
  .side-by-side-container {
    flex-direction: column; /* Stack items vertically on small screens */
    align-items: center; /* Center items */
  }
}

.side-by-side-container ul {
  flex: 1;
  margin: 0;
  padding: 0 20px 0 0;
}

.side-by-side-container li {
  margin-bottom: 0.5em; /* or try 1em for more spacing */
}

.side-by-side-container picture {
  flex: 1;
  max-width: 400px;
}

.side-by-side-container img {
  width: 100%;
  height: auto;
  display: block;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 12px;
}

.large {
  grid-column: 1 / span 2;
  grid-row: 1 / span 2;
  aspect-ratio: 1 / 1;
  width: 100%;
}

.large img {
  width: 100%;
  height: 100%;
  display: block;
  box-sizing: border-box;
  border: 2px solid #aaa;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  border-radius: 8px;

  object-fit: cover;
}

/* =========================
   Home: discovery row
   (Random sample + Recently updated)
   ========================= */

.home-discovery-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  align-items: start;
}

@media (max-width: 800px) {
  .home-discovery-row {
    grid-template-columns: 1fr;
  }
}

/* Recently updated list */
.recent-updates-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Card */
.recent-update-item {
  border: 1px solid var(--rule);
  border-radius: 0;
  overflow: hidden;
  background: var(--ground-2);
  transition: background 0.2s ease;
}

.recent-update-item:hover { background: var(--ground-3); }

/* Make the whole row clickable + control layout here */
.recent-update-link {
  display: grid;
  grid-template-columns: 96px 1fr; /* larger thumb */
  gap: 12px;
  align-items: center;
  padding: 10px;
  text-decoration: none;
  color: inherit;
}

/* Thumbnail wrapper + overlay */
.recent-update-thumb {
  position: relative;
  width: 96px;
  height: 96px;
  overflow: hidden;
  display: block;
}

.recent-update-thumb picture,
.recent-update-thumb img {
  width: 100%;
  height: 100%;
  display: block;
}

.recent-update-thumb img {
  object-fit: cover;
}

/* Date badge overlay */
.recent-update-date {
  position: absolute;
  right: 0;
  bottom: 0;
  padding: 3px 6px;
  border-radius: 0;
  background: rgba(24, 19, 12, 0.72);
  color: var(--on-dark);
  font-family: var(--data);
  font-size: 9.5px;
  line-height: 1.3;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  backdrop-filter: blur(2px);
}

/* Meta text (smaller than before) */
.recent-update-meta {
  min-width: 0; /* allow ellipsis */
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.recent-update-title {
  margin: 0;
  font-family: var(--display);
  font-size: 1.15rem;
  line-height: 1.15;
  font-weight: 400;
  color: var(--ink);
  overflow: auto;
  text-overflow: ellipsis;
}

.recent-update-description {
  margin: 0;
  font-size: 0.8rem; /* smaller */
  color: var(--ink-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;  
  overflow: hidden;
  text-overflow: ellipsis;
}

.recent-update-subtitle {
  margin: 0;
  font-size: 0.8rem; /* smaller */
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.recent-update-time {
  margin: 0;
  font-size: 0.75rem; /* smaller */
  color: #888;
}

/* Skeleton loading */
.skeleton-item {
  border-color: #ededed;
}

.skeleton-thumb {
  width: 96px;   /* match new thumb size */
  height: 72px;  /* match new thumb size */
  border-radius: 10px;
  background: var(--ground-2);
  overflow: hidden;
  position: relative;
}

.skeleton-meta {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.skeleton-line {
  height: 10px;
  border-radius: 999px;
  background: var(--ground-2);
  overflow: hidden;
  position: relative;
}

/* widths for placeholder lines */
.w-70 { width: 70%; }
.w-50 { width: 50%; }
.w-30 { width: 30%; }

/* shimmer animation */
.skeleton-thumb::after,
.skeleton-line::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent);
  animation: shimmer 1.2s;
}

.skeleton-thumb:hover::after,
.skeleton-line:hover::after {
  animation-play-state: paused;
}

@keyframes shimmer {
  100% { transform: translateX(100%); }
}

/* Full-width section spacing */
#recently-updated-row {
  margin-top: 32px;
}

/* Two-column grid */
.recent-updates-grid {
  list-style: none;
  margin: 0;
  padding: 0;

  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

/* One column on smaller screens */
@media (max-width: 800px) {
  .recent-updates-grid {
    grid-template-columns: 1fr;
  }
}

/* Home callout card */
.home-callout {
  margin: 18px 0;
}

/* Make the whole thing clickable and aligned */
.home-callout-btn {
  width: 100%;
  /* Include the padding + border in the 100% width; otherwise (content-box) the
     button is 38px wider than its container and spills past the viewport on mobile,
     where the wrapper has no side margins to absorb it (horizontal scroll). */
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 16px;

  padding: 18px 18px;
  border-radius: 0;

  border: 1px solid var(--rule);
  background: var(--ground-2);
  color: var(--ink);
  font-family: inherit;

  cursor: pointer;              /* cursor change */
  text-align: left;             /* prevent centered weirdness */
  transition: background 0.2s ease, border-color 0.2s ease;
}

/* Hover/focus affordance */
.home-callout-btn:hover {
  border-color: var(--rule-2);
  background: var(--ground-3);
}

.home-callout-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Icon */
.home-callout-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.home-callout-icon-image {
  width: 56px;
  height: 56px;
  object-fit: contain;
  display: block;
}

/* The journal callout has no raster icon, so it reuses the drawer's line glyph,
   which is drawn at 16px there. */
.home-callout-icon .drawer-icon {
  width: 56px;
  height: 56px;
  flex-basis: 56px;
}

/* Text stack */
.home-callout-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0; /* allows wrapping without layout breaking */
}

.home-callout-title {
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.4rem;
  line-height: 1.15;
  color: var(--ink);
}

.home-callout-body {
  color: var(--ink-2);
  font-size: 0.95rem;
  line-height: 1.45;
}

/* CTA on the right (button-like label) */
.home-callout-cta {
  flex: 0 0 auto;
  font-family: var(--data);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: var(--caps);
  color: var(--ink-2);
  padding: 8px 12px;
  border-radius: 0;
  border: 1px solid var(--rule-2);
  background: transparent;
  white-space: nowrap;
}

/* Mobile: stack nicer */
@media (max-width: 600px) {
  .home-callout-btn {
    flex-direction: column;     /* stack */
    align-items: center;
    text-align: center;
    gap: 10px;
    padding: 14px 14px;
  }

  .home-callout-icon-image {
    width: 44px;               /* slightly smaller than desktop */
    height: 44px;
  }

  .home-callout-icon .drawer-icon {
    width: 44px;
    height: 44px;
    flex-basis: 44px;
  }

  .home-callout-text {
    align-items: center;        /* center the text stack */
    gap: 6px;
  }

  .home-callout-title {
    font-size: 1.05rem;         /* reduce a bit */
    line-height: 1.2;
  }

  .home-callout-body {
    font-size: 0.95rem;
    line-height: 1.35;
    max-width: 36ch;            /* prevents super-wide lines on larger phones */
  }

  /* CTA becomes a real button row */
  .home-callout-cta {
    width: 100%;
    text-align: center;
    padding: 10px 12px;
    border-radius: 10px;        /* less “pill”, more button */
    white-space: normal;        /* allow wrap if needed */
  }
}



/* Journal */
/* Noto Sans (loaded above) for journal text so Cypriot carons render correctly;
   Arial stays as the fallback for any glyphs outside the subset. */
.journal-entry, .journal-index, .journal-hero {
  font-family: 'Noto Sans', 'Arial', sans-serif;
}

.journal-entry, .journal-index {
  max-width: 72ch;
  margin: 0 auto;
}

/* Full-bleed entry hero with the article's cover as backdrop */
.journal-hero {
  position: relative;
  width: 100%;
  /* Reset the generic `header { padding: 20px }` rule: with content-box sizing that
     padding would push the full-width hero 40px past the viewport (horizontal overflow).
     The full-bleed hero has no padding of its own; .journal-hero-inner pads the content. */
  padding: 0;
  box-sizing: border-box;
  min-height: clamp(280px, 52vh, 520px);
  display: flex;
  align-items: flex-end;
  background-color: #2a2420;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Darken towards the bottom so the text card always reads cleanly */
.journal-hero--image::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(20, 16, 12, 0.05) 0%,
    rgba(20, 16, 12, 0.35) 45%,
    rgba(20, 16, 12, 0.80) 100%);
}

.journal-hero-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  /* Match the article's centred reading column so the hero card lines up with the text
     below it instead of sitting in a wider, left-aligned 1000px box. The article text is
     inset by 40px each side (20px from .main-section-wrapper + 20px from `main`), so the
     hero uses the same 72ch max-width and 40px side padding to align on every width. */
  max-width: 72ch;
  margin: 0 auto;
  padding: 0 40px 40px;
  box-sizing: content-box;
}

/* Semi-transparent frosted panel holding the title/meta/tags */
.journal-hero-card {
  max-width: 720px;
  padding: 22px 26px;
  border-radius: 0;
  background: rgba(20, 16, 12, 0.42);
  backdrop-filter: blur(10px) saturate(1.1);
  -webkit-backdrop-filter: blur(10px) saturate(1.1);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
  color: #fff;
}

/* Back-to-index link at the top of the entry hero, so readers can return to the
   journal index without opening the sidebar. */
.journal-hero-back {
  display: inline-block;
  margin-bottom: 12px;
  color: rgba(255, 255, 255, 0.92);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.journal-hero-back:hover,
.journal-hero-back:focus-visible {
  text-decoration: underline;
}

.journal-entry-title {
  margin: 0 0 8px 0;
}

.journal-hero .journal-entry-title {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: clamp(1.9rem, 4.5vw, 3.2rem);
  font-weight: 400;
  line-height: 1.08;
  color: #fff;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.4);
}

.journal-entry-meta {
  color: #535353;
  font-size: 0.95rem;
}

.journal-hero .journal-entry-meta {
  color: rgba(255, 255, 255, 0.92);
}

.journal-entry-sep {
  margin: 0 8px;
}

.journal-entry-summary {
  margin: 10px 0 0 0;
  color: #909090;
}

.journal-hero .journal-entry-summary {
  color: rgba(255, 255, 255, 0.94);
  font-size: 1.05rem;
}

@media (max-width: 600px) {
  .journal-hero-card {
    padding: 18px 18px;
  }
}

/* Auto-generated table of contents */
.journal-toc {
  margin: 0 0 26px 0;
  padding: 14px 20px;
  background-color: var(--ground-3);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0;
  font-size: 0.95rem;
  line-height: 1.5;
}

.journal-toc summary {
  cursor: pointer;
  font-weight: bold;
  color: var(--ink);
  text-transform: var(--caps);
  letter-spacing: 0.04em;
  font-size: 0.9rem;
}

.journal-toc ul {
  list-style: none;
  margin: 12px 0 2px 0;
  padding: 0;
}

.journal-toc li {
  display: block;
  margin: 0;
  padding: 5px 0;
}

.journal-toc li + li {
  border-top: 1px solid var(--rule);
}

.journal-toc li.toc-h2 {
  padding-left: 22px;
  font-size: 0.92em;
}

.journal-toc li.toc-h3 {
  padding-left: 44px;
  font-size: 0.88em;
}

.journal-toc a {
  text-decoration: none;
  color: var(--ink-2);
}

.journal-toc a:hover {
  text-decoration: underline;
}

/* Bottom "← Journal" back link. Without an explicit colour it inherits the generic
   `nav a { color: #fff }` (meant for the dark site header) and vanishes on the light
   page background, so give it the same brown accent as the TOC links. */
.journal-entry-nav {
  margin-top: 28px;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
}

.journal-entry-nav a {
  color: var(--ink-2);
  text-decoration: none;
  font-weight: 600;
}

.journal-entry-nav a:hover,
.journal-entry-nav a:focus-visible {
  text-decoration: underline;
}

/* Markdown content */
.journal-entry-content {
  line-height: 1.65;
}

.journal-entry-content img,
.journal-entry-content video {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  display: block;
}

.journal-entry-content figure {
  margin: 18px 0;
}

.journal-entry-content figcaption {
  margin-top: 8px;
  color: var(--ink-3);
  font-size: 0.9rem;
}

/* Index list */
.journal-index-list {
  list-style: none;
  padding: 0;
  margin: 16px 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.journal-index-item {
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--ground-3);
  overflow: hidden;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.journal-index-item:hover {
  box-shadow: 0 6px 20px rgba(30, 25, 20, 0.12);
  transform: translateY(-2px);
}

.journal-index-link {
  display: flex;
  align-items: stretch;
  gap: 0;
  text-decoration: none;
  color: inherit;
}

.journal-index-thumb {
  flex: 0 0 200px;
  align-self: stretch;
  overflow: hidden;
  background: #efeae4;
}

.journal-index-thumb img {
  width: 100%;
  height: 100%;
  min-height: 130px;
  object-fit: cover;
  display: block;
}

.journal-index-body {
  flex: 1 1 auto;
  min-width: 0;
  padding: 14px 16px;
}

@media (max-width: 560px) {
  .journal-index-link {
    flex-direction: column;
  }
  .journal-index-thumb {
    flex-basis: 170px;
    width: 100%;
  }
}

.journal-index-title {
  font-weight: 800;
  margin-bottom: 4px;
}

.journal-index-meta {
  color: var(--ink-3);
  font-size: 0.9rem;
}

.journal-index-summary {
  margin-top: 8px;
  color: #444;
}

/* Sort control. Two states, so a pair of buttons rather than a select: the
   choice is visible without opening anything. */
.journal-sort {
  display: flex;
  gap: 6px;
  margin-top: 14px;
}

.journal-sort-btn {
  font-family: var(--data);
  font-size: 0.78rem;
  letter-spacing: var(--caps-tracking, 0.09em);
  text-transform: var(--caps);
  padding: 5px 12px;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
}

.journal-sort-btn:hover {
  color: var(--ink);
  border-color: var(--rule-2);
}

/* The label takes the ground colour, not --on-dark: in the dark palette --ink is
   the parchment one and the text has to come back the other way. */
.journal-sort-btn.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
}

/* The count is a snapshot taken when the page was built, so it sits quietly
   beside the date instead of announcing itself. */
.journal-reads {
  font-variant-numeric: tabular-nums;
}

/* Responsive video embeds (journal) */
.journal-entry-content .video-embed {
  position: relative;
  width: 100%;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  margin: 18px 0;
}

.journal-entry-content .video-embed iframe,
.journal-entry-content .video-embed video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 8px;
}

/* ============================================================
   Taxon page (redesigned)
   ============================================================ */

/* Wider canvas on taxon pages — AI illustrations deserve room */
body:has(.taxon-hero) .main-section-wrapper {
  max-width: 1300px;
}
body:has(.taxon-hero) main {
  padding: 20px 8px;
}
body:has(.taxon-hero) section {
  padding: 1rem 0.5rem;
}

.taxon-hero {
  display: block;
  padding: 1.6rem 0 1.2rem;
  position: relative;
  text-align: left;
  border-bottom: 1px solid var(--rule-2);
  margin-bottom: 1.8rem;
}

/* A locality is about exactly one stretch of time, so the rule under its name is
   that interval's ICS colour. A taxon usually spans several and keeps the
   hairline.

   Three pixels with a hairline beneath rather than a two-pixel rule on its own:
   half the ICS palette is pale — the Pliocene is #FFFF99 — and a pale hairline
   on parchment is not there at all. The hairline gives every colour an edge to
   sit on, so the band reads as a band whatever colour it happens to be. */
.locality-page .taxon-hero {
  border-bottom: 3px solid var(--period);
  box-shadow: 0 1px 0 var(--rule-2);
}

.taxon-hero h1 {
  font-family: var(--display);
  font-size: clamp(2.4rem, 6.5vw, 4.6rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0;
  line-height: 1;
  text-wrap: balance;
}

/* The counts under the name are the page's own record, so they are set in the
   data voice rather than as a sentence. */
.taxon-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 5px 20px;
  margin-top: 1.1rem;
}

.taxon-facts .taxon-fact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: var(--caps);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.icon-pin {
  width: 12px;
  height: 12px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  flex-shrink: 0;
}

/* The illustration and the silhouette are two views of the same animal, so they
   stack: the reconstruction first, the shape it leaves in the record beneath. */
.story-visuals {
  display: block;
  margin: 0 0 1.5rem;
}

.story-illustration {
  min-width: 0;
  margin: 0;
  display: block;
}

.story-illustration img.tax-page-image {
  width: 100%;
  max-width: 100%;
  height: auto;
  max-height: none;
  border-radius: 0;
  margin: 0;
  background: var(--plate);
  border: 1px solid var(--rule-2);
  box-shadow: var(--lift);
  display: block;
}

.story-phylopic {
  margin: 14px 0 0;
  width: 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px 0 4px;
  border-top: 1px solid var(--rule);
}

.story-phylopic img {
  width: auto;
  height: auto;
  max-width: 60%;
  max-height: 130px;
  object-fit: contain;
  opacity: 0.9;
  display: block;
  margin: 0 auto;
}

/* The etymology used to sit in a column beside the description, which halved the
   measure of both. It now follows the description as an aside. */
.story-text {
  display: flex;
  flex-direction: column;
  gap: 0;
  align-items: stretch;
  min-width: 0;
}

.story-text .story-main { min-width: 0; }

.story-text .story-aside { min-width: 0; }

.taxon-fossils {
  display: flex;
  flex-direction: column;
  gap: 3rem;
  padding: 1rem 0.5rem 2rem;
}

/* A locality group is a field card, collapsed until asked for. --loc is the ICS
   colour of that locality's period, written onto the element by the generator,
   so the rail tells you when you are before you have read a word.

   The ICS colours are mixed for a white chart. Left raw on the dark ground they
   glare, so the dark palette takes them as a shade: same hue, laid into the
   card's own ground, with the light ink on top.                              */
.locality-block {
  --loc: var(--accent);
  --rail-bg: var(--loc);
  --rail-ink: #221b12;
  --rail-rule: rgba(34, 27, 18, 0.22);
  background: var(--ground-2);
  border: 1px solid var(--rule);
  border-radius: 0;
  overflow: clip;
  box-shadow: var(--lift);
  transition: box-shadow 0.25s var(--ease), transform 0.25s var(--ease);
  /* The ground the open card's watermark is measured against. */
  position: relative;
}

:root[data-theme="dark"] .locality-block {
  --rail-bg: color-mix(in srgb, var(--loc) 32%, var(--ground-2));
  --rail-ink: var(--ink);
  --rail-rule: rgba(244, 234, 214, 0.14);
}

:root[data-theme="dark"] .locality-block[open] {
  --rail-bg: color-mix(in srgb, var(--loc) 32%, var(--ground-3));
}

.locality-block:hover {
  box-shadow: var(--lift-2);
}

.locality-block[open] {
  box-shadow: var(--lift-2);
  background: var(--ground-3);
}

@keyframes localityOpen {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.locality-block[open] .gallery {
  animation: localityOpen 0.28s ease-out;
}

/* The head of the card: the photographs and their caption on the left, the age
   rail hard against the right edge.

   Deliberately unpositioned. The watermark inside it is measured against the card,
   and a positioned header would capture it and crop it to the head, so the head's
   contents are lifted over the watermark one by one instead. */
.locality-header {
  display: flex;
  align-items: stretch;
  padding: 0;
  cursor: pointer;
  list-style: none;
  border-bottom: none;
  margin-bottom: 0;
  background: transparent;
}

.locality-header:hover {
  background: var(--ground-3);
}

.locality-header::-webkit-details-marker {
  display: none;
}

.locality-header::marker {
  display: none;
}

.card-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: stretch;
  position: relative;
  z-index: 1;
}

/* The plates, at the photographs' own 16:9 so no fossil is cropped out of its
   own preview. One photograph takes the block whole rather than a quarter of it. */
.card-plates {
  /* A share of the card rather than a fixed width: on a wide screen the page has
     no measure of its own, and a 324px block of photographs marooned beside a
     1000px column of empty parchment is the problem this card was fixing. */
  flex: 0 0 clamp(260px, 34%, 420px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  background: var(--rule-2);
  border-right: 1px solid var(--rule-2);
}

.card-plates-1 { grid-template-columns: 1fr; }
.card-plates-2 { grid-template-columns: 1fr 1fr; }

/* Six photographs take a wider share of the card than four, or each of them ends
   up smaller than the preview they replaced. */
.card-plates-3 {
  grid-template-columns: 1fr 1fr 1fr;
  flex-basis: clamp(320px, 46%, 560px);
}

.card-plate {
  display: block;
  overflow: hidden;
  background: var(--plate);
  aspect-ratio: 16 / 9;
}

.card-plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  margin: 0;
  display: block;
}

/* align-items matters here: these are flex items, so a link declaring itself
   inline-block is blockified and stretches the whole column. That made a band of
   dead space to the right of the name open the taxon page instead of the card. */
.card-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.4rem;
  padding: 1.2rem 1.3rem;
  position: relative;
}

/* The exception: the count and the chevron share a line that has to reach the
   card's edge, so the chevron can sit at the far end of it. */
.card-footrow {
  align-self: stretch;
}

/* ── The watermark ─────────────────────────────────────────────────────────
   The group's illustration, printed across the card it belongs to.

   Pinned to the top of the card, as wide as the card and square, because the
   paintings are square. Its box does not depend on the card's height, which is
   the whole point: opening the card does not re-centre or rescale it, it just
   uncovers more of it. The card is a window onto a painting that is already
   there, rather than a picture that jumps when you knock on it.

   It lives inside the summary because a closed <details> hides everything else it
   holds, and it is the summary's only child that must survive the collapse. */
.card-watermark {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  aspect-ratio: 1 / 1;
  z-index: 0;
  display: block;
  pointer-events: none;
  opacity: 0.28;
}

.card-watermark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center top;
  margin: 0;
  display: block;
}

/* The paintings are lit for parchment; on the dark ground they are the brightest
   thing on the page, so they come down further to stay a ground. */
:root[data-theme="dark"] .card-watermark {
  opacity: 0.16;
}

.card-text > * {
  position: relative;
  z-index: 1;
}

/* Wide, the chevron sits at the card's right margin, beside the rail; narrow it
   moves down next to the count, because by then that margin is the band's. */
.card-footrow > .locality-toggle {
  display: none;
}

.locality-name-link {
  text-decoration: none;
  color: inherit;
  display: inline-block;
}

/* The name is the caption on the photographs now, not the thing the card is
   made of, so it stops shouting over them. */
.locality-name {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--ink);
  transition: color 0.2s ease;
}

.locality-name-link:hover .locality-name {
  color: var(--accent);
}

/* The count is a figure, not a badge; it sits in the data voice beside the name
   with the camera mark the specimen plates use. */
.locality-count {
  font-family: var(--data);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: var(--caps);
  color: var(--ink-3);
  background: transparent;
  padding: 0;
  border-radius: 0;
  box-shadow: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-variant-numeric: tabular-nums;
}

/* A chevron that turns, rather than a plus that becomes a cross. */
.locality-toggle {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  align-self: center;
  margin: 0 0.9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  font-size: 0;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  transition: transform 0.3s var(--ease), color 0.2s ease;
}

.locality-toggle::before {
  content: "";
  width: 9px;
  height: 9px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
}

.locality-block:hover .locality-toggle {
  color: var(--ink);
}

.locality-block[open] .locality-toggle {
  transform: rotate(180deg);
  color: var(--ink);
}

.locality-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.6rem;
  align-items: center;
  font-family: var(--data);
  font-size: 10.5px;
  text-transform: var(--caps);
  letter-spacing: 0.11em;
  font-weight: 400;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.locality-meta > *::before {
  content: "·";
  margin-right: 0.6rem;
  color: var(--rule-2);
  font-weight: 400;
}

.locality-meta > *:first-child::before {
  content: "";
  margin: 0;
}

.locality-formation {
  color: var(--ink-3);
}

.locality-flag {
  font-size: 1rem;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
}

/* ── The age rail ──────────────────────────────────────────────────────────
   The right-hand edge of the card, in the ICS colour of its period, with the
   figure set large and the interval name as its caption: on a card the reader
   is scanning, "201–190" places the fossil faster than "Lower Jurassic" does.
   It widens when the card opens, which is the one gesture the card has.

   A locality page's cards all share the page's single age, so there the rail is
   left bare — colour and nothing else, since printing the same span seven times
   tells the reader nothing.                                                   */
.age-rail {
  flex: 0 0 auto;
  width: 112px;
  background: var(--rail-bg);
  color: var(--rail-ink);
  border-left: 1px solid var(--rail-rule);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.9rem 0.5rem;
  text-align: center;
  transition: width 0.32s var(--ease), background 0.25s ease;
  position: relative;
  z-index: 1;
}

.age-rail-bare {
  width: 12px;
  padding: 0;
}

.age-figure {
  font-family: var(--display);
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  transition: font-size 0.32s var(--ease);
}

/* The unit stays in its natural case: "MILLION YEARS AGO" tracked out in capitals
   needs three lines of a 112px rail, and the figure is what the reader came for. */
.age-unit {
  font-family: var(--data);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  line-height: 1.25;
  opacity: 0.68;
  margin-top: 3px;
}

.age-interval {
  font-family: var(--data);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: var(--caps);
  line-height: 1.3;
  opacity: 0.8;
  margin-top: 0.55rem;
  transition: font-size 0.32s var(--ease);
}

.locality-block[open] .age-rail {
  width: 168px;
}

.locality-block[open] .age-rail-bare {
  width: 12px;
}

.locality-block[open] .age-figure {
  font-size: 2.35rem;
}

.locality-block[open] .age-interval {
  font-size: 11px;
}

/* ── The card, narrow ──────────────────────────────────────────────────────
   The photographs take the whole width rather than sharing a line with the
   text, and the age leaves the right-hand edge for a band across the top, where
   it reads the normal way round. What stays behind on the right is a thin edge
   of the same colour, drawn as the card's own border so it runs the full height
   and meets the band with no seam.

   The viewport and not the card: these cards are always the full width of the
   page's one column, so the window is the honest measure, and a container query
   cannot restyle the element that declares itself the container anyway.       */
@media (max-width: 700px) {
  .locality-block {
    border-right: 10px solid var(--loc);
  }

  :root[data-theme="dark"] .locality-block {
    border-right-color: var(--rail-bg);
  }

  .locality-header,
  .card-body {
    flex-direction: column;
  }

  .card-plates {
    flex: 0 0 auto;
    width: 100%;
    border-right: 0;
    border-bottom: 1px solid var(--rule-2);
  }

  .card-text {
    padding: 0.9rem 1rem 1rem;
    gap: 0.3rem;
  }


  .card-body > .locality-toggle {
    display: none;
  }

  .card-footrow {
    display: flex;
    align-items: center;
    gap: 0.8rem;
  }

  .card-footrow > .locality-toggle {
    display: flex;
    margin: 0 0 0 auto;
  }

  /* One line: "100–94 million years ago · LATE CRETACEOUS". The pieces are sized
     to fit a 360px phone, and each is unbreakable, so the longest Greek intervals
     fall to a clean second line rather than snapping a figure in half. */
  .age-rail {
    order: -1;
    width: auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem;
    padding: 0.45rem 0.7rem;
    border-left: 0;
    border-bottom: 1px solid var(--rail-rule);
    text-align: left;
  }

  .locality-block[open] .age-rail {
    width: auto;
    padding: 0.6rem 0.7rem;
  }

  /* Bare on a locality page: the band would be an empty stripe, so there is none
     and the card's coloured edge carries the period on its own. */
  .age-rail-bare,
  .locality-block[open] .age-rail-bare {
    display: none;
  }

  .age-figure,
  .age-unit,
  .age-interval {
    white-space: nowrap;
  }

  .age-figure,
  .locality-block[open] .age-figure {
    font-size: 1.3rem;
  }

  .age-unit {
    font-size: 9px;
    letter-spacing: 0.01em;
    margin: 0;
  }

  .age-interval,
  .locality-block[open] .age-interval {
    margin-top: 0;
    font-size: 9px;
    letter-spacing: 0.05em;
  }

  /* The same mark the meta line uses, so the band reads as one sentence rather
     than three labels that happen to share a stripe. */
  .age-interval::before {
    content: "·";
    margin-right: 0.3rem;
    letter-spacing: 0;
    opacity: 0.7;
  }
}

/* The catalogue grid: even columns, even gutters, every plate the same size. */
.locality-block .gallery,
.taxon-fossils .gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 16px;
  justify-content: initial;
  margin: 0;
  padding: 1.2rem;
  position: relative;
  z-index: 1;
}

/* The illustration column and the reading column. The picture holds its own
   width so the description keeps a comfortable measure beside it. */
.taxon-story {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
  padding: 0;
}

.story-aside {
  background: var(--ground-2);
  border: 1px solid var(--rule);
  border-radius: 0;
  padding: 1.2rem 1.4rem;
  position: relative;
  margin-top: 1.6rem;
}

.story-eyebrow {
  margin: 0 0 0.7rem;
  font-family: var(--data);
  font-size: 11px;
  font-weight: 400;
  text-transform: var(--caps);
  letter-spacing: 0.11em;
  color: var(--ink-3);
}

.story-aside .etymology-text p {
  margin: 0.3rem 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-2);
}

.taxon-sub {
  padding: 0;
}

.taxon-sub .story-eyebrow {
  text-align: left;
  margin-bottom: 1.1rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule-2);
}

.subtaxa-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 18px;
  justify-content: initial;
}

/* Image and caption are one bounded card, as on the specimen plates. Loose in a
   grid, a caption sits between two pictures and belongs to neither of them at a
   glance — the reader has to work out whether it names the thing above or the
   thing below, which is not a question a caption should raise. */
.subtaxa-card {
  max-width: none;
  text-align: left;
  text-decoration: none;
  color: var(--ink);
  padding: 0;
  background: var(--ground-2);
  border: 1px solid var(--rule-2);
  border-radius: 0;
  box-shadow: var(--lift);
  overflow: hidden;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
  display: block;
}

.subtaxa-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-2);
}

.subtaxa-card img.tax-thumbnail-image {
  width: 100%;
  max-width: none;
  margin: 0;
  background: var(--plate);
  border: 0;
  border-bottom: 1px solid var(--rule);
  box-shadow: none;
}

.subtaxa-card-name {
  margin: 0.7rem 0.8rem 0.3rem;
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1.15;
}

.subtaxa-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.7rem;
  margin: 0 0.8rem 0.7rem;
  justify-content: flex-start;
  align-items: center;
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: var(--caps);
  color: var(--ink-3);
}

.subtaxa-card-count {
  background: transparent;
  color: var(--ink-3);
  padding: 0;
  border-radius: 0;
  font-size: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-variant-numeric: tabular-nums;
}

.subtaxa-card-extinct .subtaxa-card-name {
  color: var(--ink-2);
}

.subtaxa-card-extinct img.tax-thumbnail-image {
  opacity: 0.85;
}

/* Mobile: collapse story columns, tighten paddings */
@media (max-width: 720px) {
  body:has(.taxon-hero) main {
    padding: 12px 4px;
  }
  body:has(.taxon-hero) section {
    padding: 0.75rem 0.3rem;
  }
  .taxon-hero {
    padding: 1.2rem 0.5rem 1rem;
  }
  .taxon-hero h1 {
    font-size: 2rem;
  }
  .story-visuals {
    grid-template-columns: 1fr;
    gap: 0.8rem;
  }
  .story-illustration img.tax-page-image {
    width: 100%;
    max-width: 100%;
  }
  .story-text {
    flex-direction: column;
    gap: 1rem;
  }
  .story-text .story-main,
  .story-text .story-aside {
    flex: 1 1 auto;
    width: 100%;
    box-sizing: border-box;
  }
  .story-phylopic {
    max-width: 60%;
    margin: 0 auto;
  }
  .story-phylopic img {
    max-height: 12rem;
  }
  .taxon-fossils {
    gap: 1.5rem;
    padding: 0.5rem 0.25rem 1rem;
  }
  .locality-name {
    font-size: 1.3rem;
  }
  .locality-meta {
    font-size: 0.68rem;
    letter-spacing: 0.08em;
  }
  .locality-count {
    font-size: 10px;
  }
  .locality-toggle {
    width: 24px;
    height: 24px;
  }
  .locality-block .gallery,
  .taxon-fossils .gallery {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
    padding: 0.8rem;
  }
}

/* ============================================================
   Acknowledgements page
   ============================================================ */

.acknowledgements-page {
  padding: 1rem 0.5rem 2rem;
}

.acknowledgements-page h1 {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 2.4rem;
  font-weight: 400;
  margin: 0 0 0.5rem;
  color: var(--ink);
}

.acknowledgements-page > p {
  font-size: 1.05rem;
  color: var(--ink-2);
  margin: 0 0 1.5rem;
}

.ack-section {
  margin: 2rem 0;
  padding: 1.25rem 1.4rem;
  background: var(--ground-3);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0;
}

.ack-section h2 {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 1.6rem;
  font-weight: 400;
  margin: 0 0 0.5rem;
  color: var(--ink);
}

.ack-section > p {
  margin: 0.4rem 0;
  color: var(--ink-2);
}

.ack-source-list {
  list-style: disc;
  padding-left: 1.5rem;
  margin: 0.6rem 0 0;
}

.ack-source-list li {
  padding: 0.2rem 0;
  color: var(--ink-2);
}

.attribution-list {
  list-style: none;
  padding: 0;
  margin: 1rem 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0.6rem 1.2rem;
}

.attribution-list li {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid #f0e9da;
}

.attr-thumb-link {
  flex: 0 0 auto;
  display: block;
  width: 56px;
  height: 56px;
  background: var(--ground-3);
  border: 1px solid var(--rule);
  border-radius: 0;
  padding: 4px;
  box-sizing: border-box;
}

.attr-thumb {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.attr-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.attr-taxon {
  font-style: italic;
  color: var(--ink);
  font-weight: 500;
}

.attr-artist {
  font-size: 0.92rem;
  color: var(--ink-2);
}

.attr-license {
  font-size: 0.78rem;
  color: var(--ink-3);
  text-decoration: none;
  text-transform: var(--caps);
  letter-spacing: 0.04em;
}

.attr-license:hover {
  color: var(--accent);
  text-decoration: underline;
}

@media (max-width: 720px) {
  .acknowledgements-page h1 {
    font-size: 1.9rem;
  }
  .ack-section {
    padding: 1rem 0.9rem;
    margin: 1.2rem 0;
  }
  .ack-section h2 {
    font-size: 1.3rem;
  }
  .attribution-list {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   Quiz page
   ============================================================ */

.quiz-page {
  padding: 1rem 0.5rem 2rem;
  max-width: 760px;
  margin: 0 auto;
}

.quiz-card {
  background: var(--ground-3);
  border: 1px solid var(--rule);
  border-radius: 0;
  padding: 1.5rem 1.6rem;
  box-shadow: 0 4px 14px rgba(30, 25, 20, 0.08);
}

.quiz-card h1 {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 2.2rem;
  font-weight: 400;
  margin: 0 0 0.8rem;
  color: var(--ink);
  text-align: center;
}

.quiz-card p {
  margin: 0.5rem 0;
  color: var(--ink);
  font-size: 1.05rem;
}

.quiz-primary-btn {
  display: block;
  width: 100%;
  margin: 1.2rem 0 0;
  padding: 0.8rem 1.2rem;
  font-size: 1.05rem;
  font-weight: 600;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.quiz-primary-btn:hover {
  background: #6d4521;
}

.quiz-secondary-btn {
  padding: 0.55rem 1.1rem;
  font-size: 0.95rem;
  font-weight: 500;
  background: var(--ground-3);
  color: var(--ink-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.quiz-secondary-btn:hover {
  background: var(--ground-2);
}

.quiz-progress-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.9rem;
  color: var(--ink-3);
  text-transform: var(--caps);
  letter-spacing: 0.1em;
  margin-bottom: 1rem;
  font-weight: 600;
}

:lang(el) .quiz-progress-bar,
:lang(grc) .quiz-progress-bar {
  text-transform: none;
  letter-spacing: 0.04em;
}

.quiz-score-display strong {
  color: var(--accent);
  font-size: 1.1rem;
}

.quiz-prompt {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 1.4rem;
  text-align: center;
  margin: 0.5rem 0 1rem;
  color: var(--ink);
}

.quiz-media {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0.8rem 0 1.2rem;
  min-height: 80px;
}

.quiz-media figure {
  margin: 0;
  text-align: center;
}

.quiz-media-caption {
  font-style: italic;
  color: var(--ink-2);
  margin-top: 0.4rem;
  font-size: 1.05rem;
}

.quiz-image-reveal {
  display: inline-block;
  background: linear-gradient(135deg, #2a2018 0%, #15100a 100%);
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 4px 14px rgba(30, 25, 20, 0.2);
}

.quiz-image-reveal.silhouette-bg {
  background: var(--ground-3);
  border: 1px solid var(--rule);
}

/* "Who's That Pokémon?" silhouette frame — radial yellow blast, deep-blue
   border ring, yellow outer halo, giant ghosted "?" behind the black
   silhouette, twinkling sparkles. After answer: .revealed plays a flash
   animation and brings the colour AI illustration in. */
.quiz-pokemon-frame {
  position: relative;
  display: inline-block;
  margin-top: 1.2rem;
  background:
    radial-gradient(ellipse at 25% 25%, rgba(255, 255, 255, 0.55) 0%, transparent 55%),
    radial-gradient(circle at center, #fff8c4 0%, #ffd54d 50%, #f08e1c 100%);
  border: 8px solid #2c2c8a;
  border-radius: 22px;
  padding: 2.2rem 2.6rem 1.5rem;
  box-shadow:
    0 0 0 4px #ffcb05,
    0 10px 30px rgba(30, 25, 20, 0.35),
    inset 0 0 32px rgba(255, 255, 255, 0.5);
  overflow: hidden;
  max-width: 100%;
  box-sizing: border-box;
}

/* Big ghosted question mark behind the silhouette. */
.quiz-pokemon-frame::before {
  content: "?";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'GFS Didot', Georgia, serif;
  font-size: 16rem;
  font-weight: 900;
  color: rgba(0, 0, 0, 0.10);
  pointer-events: none;
  line-height: 1;
  z-index: 0;
  transition: opacity 0.5s ease;
}

.quiz-pokemon-frame.revealed::before {
  opacity: 0;
}

/* Comic-style floating question marks scattered around the silhouette.
   They wiggle and rotate independently for that "mystery" feel. */
.pokemon-q {
  position: absolute;
  font-family: 'GFS Didot', Georgia, serif;
  font-weight: 900;
  color: #2c2c8a;
  text-shadow: 2px 2px 0 #ffcb05, -1px -1px 0 #ffcb05, 1px -1px 0 #ffcb05, -1px 1px 0 #ffcb05;
  pointer-events: none;
  user-select: none;
  z-index: 3;
  line-height: 1;
}

.pokemon-q-1 { top: 6%;   left: 4%;  font-size: 3.2rem; transform: rotate(-18deg); animation: wiggle-q 3s ease-in-out infinite; }
.pokemon-q-2 { top: 10%;  right: 5%; font-size: 2.4rem; transform: rotate(22deg);  animation: wiggle-q 3.4s ease-in-out infinite 0.5s; }
.pokemon-q-3 { bottom: 8%; left: 7%; font-size: 2rem;   transform: rotate(-32deg); animation: wiggle-q 4.2s ease-in-out infinite 1s; }
.pokemon-q-4 { bottom: 12%; right: 8%; font-size: 2.8rem; transform: rotate(15deg); animation: wiggle-q 3.8s ease-in-out infinite 1.5s; }
.pokemon-q-5 { top: 38%;  right: 2%; font-size: 1.6rem; transform: rotate(-10deg); animation: wiggle-q 2.8s ease-in-out infinite 0.2s; color: #e63946; }
.pokemon-q-6 { bottom: 38%; left: 2%; font-size: 1.5rem; transform: rotate(12deg); animation: wiggle-q 3.2s ease-in-out infinite 0.8s; color: #e63946; }

@keyframes wiggle-q {
  0%, 100% { transform: rotate(var(--rot, -18deg)) translateY(0); opacity: 0.95; }
  50%      { transform: rotate(calc(var(--rot, -18deg) + 10deg)) translateY(-6px); opacity: 0.7; }
}

.quiz-pokemon-frame.revealed .pokemon-q {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.quiz-pokemon-frame img {
  display: block;
  max-width: min(280px, 100%);
  max-height: 280px;
  margin: 0 auto;
  filter: brightness(0) saturate(0);
  transition: filter 0.9s ease;
  position: relative;
  z-index: 1;
}

.quiz-pokemon-frame.revealed img {
  filter: none;
  animation: pokemon-reveal-flash 0.9s ease-out;
}

@keyframes pokemon-reveal-flash {
  0%   { transform: scale(0.92); filter: brightness(3) saturate(2); }
  35%  { transform: scale(1.06); filter: brightness(1.6) saturate(1.5); }
  100% { transform: scale(1);    filter: none; }
}

/* Twinkling sparkles. */
.pokemon-spark {
  position: absolute;
  width: 22px;
  height: 22px;
  z-index: 2;
  background:
    radial-gradient(circle, #fff 0%, transparent 60%),
    linear-gradient(45deg, transparent 47%, #fff 50%, transparent 53%),
    linear-gradient(-45deg, transparent 47%, #fff 50%, transparent 53%);
  pointer-events: none;
  animation: spark-twinkle 2.4s ease-in-out infinite;
}

.pokemon-spark-1 { top: 12%;    left: 8%;  animation-delay: 0s; }
.pokemon-spark-2 { top: 18%;    right: 10%; width: 16px; height: 16px; animation-delay: 0.6s; }
.pokemon-spark-3 { bottom: 16%; right: 16%; width: 18px; height: 18px; animation-delay: 1.2s; }

@keyframes spark-twinkle {
  0%, 100% { opacity: 0.95; transform: scale(1) rotate(0deg); }
  50%      { opacity: 0.35; transform: scale(0.65) rotate(180deg); }
}

.quiz-image-reveal img {
  display: block;
  border-radius: 8px;
  transition: clip-path 0.45s ease;
}

.quiz-image-reveal.reveal-0 img { clip-path: inset(38% round 8px); }
.quiz-image-reveal.reveal-1 img { clip-path: inset(18% round 8px); }
.quiz-image-reveal.reveal-2 img { clip-path: inset(0 round 8px); }

.quiz-silhouette {
  max-width: 240px;
  max-height: 240px;
}

.quiz-ai {
  display: block;
  max-width: min(280px, 100%);
  max-height: 280px;
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(30, 25, 20, 0.12);
}

/* Placeholder for the relative-game reference illustration while it is hidden
   (before a hint / answer). Sized like .quiz-ai so layout stays stable. */
.quiz-ai-hidden {
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(220px, 60vw);
  height: 180px;
  font-size: 3rem;
  font-weight: 700;
  color: #b7ac97;
  background: var(--ground-3);
  border: 1px dashed var(--rule);
}

/* Reset the browser's default ~40px figure margins so AI-image figures stay
   centered within the flex-centered .quiz-media container on every viewport. */
.quiz-media figure {
  margin: 0;
  max-width: 100%;
}

.quiz-etymology-text {
  font-style: italic;
  font-size: 1.1rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--ground-2);
  padding: 1rem 1.3rem;
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  margin: 0;
  max-width: 600px;
}

.quiz-riddle-facts {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: 500px;
}

.quiz-riddle-facts li {
  padding: 0.6rem 1rem;
  margin: 0.4rem 0;
  background: var(--ground-2);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  font-size: 1.05rem;
  color: var(--ink);
}

/* The parchment card the riddle and trivia sit on. Its ground is a token pair
   rather than two literals, because the ink above is var(--ink): left hardcoded,
   the card stayed cream while the text went light, and the dark theme rendered
   the quote invisible. */
.quiz-riddle-prose,
.quiz-trivia-text {
  --quote-top: #fbf3e3;
  --quote-bottom: #f5ead2;
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 1.2rem;
  line-height: 1.55;
  color: var(--ink);
  background: linear-gradient(180deg, var(--quote-top) 0%, var(--quote-bottom) 100%);
  padding: 1.2rem 1.5rem;
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  margin: 0;
  max-width: 600px;
  box-shadow: 0 2px 8px rgba(30, 25, 20, 0.06);
}

:root[data-theme="dark"] .quiz-riddle-prose,
:root[data-theme="dark"] .quiz-trivia-text {
  --quote-top: var(--ground-3);
  --quote-bottom: var(--ground-2);
  box-shadow: var(--lift);
}

.quiz-riddle-prose::before {
  content: "❦ ";
  color: var(--ink-3);
  font-style: normal;
  font-weight: bold;
}

.quiz-trivia-text::before {
  content: "✦ ";
  color: var(--ink-3);
  font-style: normal;
}

.riddle-label {
  text-transform: var(--caps);
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--ink-3);
  margin-right: 0.4rem;
}

:lang(el) .riddle-label,
:lang(grc) .riddle-label {
  text-transform: none;
  letter-spacing: 0.04em;
}

.quiz-choices {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.7rem;
  margin: 0.6rem 0;
}

.choice-button {
  background: var(--ground-3);
  color: var(--ink);
  border: 2px solid var(--rule);
  border-radius: 10px;
  padding: 0.7rem 0.9rem;
  font-size: 1rem;
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease;
  text-align: left;
}

.choice-button:hover:not(:disabled) {
  border-color: var(--ink-3);
  background: var(--ground-3);
}

.choice-button:disabled {
  cursor: default;
  opacity: 0.85;
}

.choice-correct {
  border-color: #5e8c41 !important;
  background: #e6f0d8 !important;
  color: #324f1f;
}

.choice-wrong {
  border-color: #b04540 !important;
  background: #f4d8d6 !important;
  color: #5e1d1a;
}

.choice-with-image {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.4rem;
}

.choice-thumb {
  width: 100%;
  max-width: 140px;
  height: 110px;
  object-fit: contain;
  border-radius: 6px;
  border: 1px solid var(--rule);
}

/* Placeholder shown in place of a choice thumbnail before the player takes a
   hint (or answers), so the image can't give the answer away. */
.choice-thumb-hidden {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 700;
  color: #b7ac97;
  background: var(--ground-3);
  border-style: dashed;
}

.choice-label {
  font-style: italic;
  font-size: 0.95rem;
}

.quiz-feedback {
  text-align: center;
  font-size: 1.1rem;
  font-weight: 600;
  min-height: 1.4em;
  margin: 0.6rem 0;
}

.feedback-correct { color: #5e8c41; }
.feedback-wrong { color: #b04540; }

/* Sort-mode click badges on choice buttons. */
.choice-button { position: relative; }

.sort-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  background: var(--accent);
  color: var(--on-accent);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.95rem;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.sort-correct-badge {
  position: absolute;
  bottom: 6px;
  left: 6px;
  background: #5e8c41;
  color: #fff;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.85rem;
}

.choice-selected {
  border-color: var(--rule-2) !important;
  background: var(--ground-3) !important;
}

/* Sort question two-zone layout */
.quiz-sort-available-label,
.quiz-sort-ordered-label {
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: var(--caps);
  color: var(--ink-3);
  margin: 0.6rem 0 0.3rem;
}

:lang(el) .quiz-sort-available-label,
:lang(el) .quiz-sort-ordered-label,
:lang(grc) .quiz-sort-available-label,
:lang(grc) .quiz-sort-ordered-label {
  text-transform: none;
  letter-spacing: 0.04em;
}

.quiz-sort-available,
.quiz-sort-ordered {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 0.6rem;
  border-radius: 10px;
  min-height: 80px;
  align-items: center;
}

.quiz-sort-available {
  background: var(--ground-3);
  border: 1px solid var(--rule);
}

.quiz-sort-ordered {
  background: var(--ground-2);
  border: 1px dashed var(--rule-2);
}

.quiz-sort-empty {
  color: var(--ink-3);
  font-style: italic;
  margin: 0 auto;
  font-size: 0.95rem;
}

.sort-item {
  flex: 0 0 auto;
  width: 150px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.sort-item .choice-thumb {
  width: 100%;
  height: 100px;
}

#quiz-sort-submit {
  margin-top: 0.8rem;
}

#quiz-sort-submit:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

@media (max-width: 720px) {
  .sort-item {
    width: 100px;
  }
  .sort-item .choice-thumb {
    height: 70px;
  }
}

.quiz-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.6rem;
}

.quiz-final-score-display {
  text-align: center;
  font-size: 1.3rem;
}

.quiz-final-score-display strong {
  color: var(--accent);
  font-size: 1.6rem;
}

@media (max-width: 720px) {
  .quiz-card {
    padding: 1rem 0.9rem;
  }
  .quiz-card h1 {
    font-size: 1.7rem;
  }
  .quiz-prompt {
    font-size: 1.15rem;
  }
  .quiz-choices {
    grid-template-columns: 1fr;
  }
  .quiz-ai {
    max-width: min(220px, 100%);
    max-height: 220px;
  }
  /* Shrink the pokémon frame's fixed chrome so the silhouette fits a phone
     screen. Target .quiz-pokemon-frame img directly — it outranks the
     .quiz-silhouette rule below on specificity. */
  .quiz-pokemon-frame {
    padding: 1.2rem 1.1rem 0.9rem;
    border-width: 5px;
  }
  .quiz-pokemon-frame img,
  .quiz-silhouette {
    max-width: min(200px, 100%);
    max-height: 200px;
  }
  .choice-thumb {
    height: 90px;
  }
}

/* ============================================================
   404 page
   ============================================================ */

.notfound-page {
  padding: 3rem 0.5rem 4rem;
  max-width: 620px;
  margin: 0 auto;
  text-align: center;
}

/* First thing on the page: the reader has to know what happened before they are
   told a joke about it. Scoped past `.notfound-page p` below, which would otherwise
   win on specificity and set it in body copy. */
.notfound-page .notfound-code {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 5.5rem;
  line-height: 1;
  letter-spacing: 0.04em;
  margin: 0 0 1.5rem;
  color: var(--ink);
}

/* The drawing restates the heading and adds nothing a reader needs in words, so it
   stays out of the accessibility tree. */
.notfound-outcrop {
  display: block;
  width: 100%;
  max-width: 460px;
  height: auto;
  margin: 0 auto 1.75rem;
}

.notfound-outcrop .strata {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1.6;
}

/* The one line doing the talking, drawn heavier than the beds it cuts off. */
.notfound-outcrop .erosion-surface {
  fill: none;
  stroke: var(--ink-2);
  stroke-width: 2.5;
  stroke-linecap: round;
}

.notfound-outcrop .outcrop-edge,
.notfound-outcrop .ground {
  fill: none;
  stroke: var(--ink-2);
  stroke-width: 2.2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* Body, head, hat and boots are masses; arms and legs are strokes. Keeping the two
   apart is what stops this reading as a stick figure. */
.notfound-outcrop .figure-fill {
  fill: var(--ink-2);
}

.notfound-outcrop .figure-limb {
  fill: none;
  stroke: var(--ink-2);
  stroke-width: 5.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.notfound-outcrop .figure-boot {
  fill: none;
  stroke: var(--ink-2);
  stroke-width: 4.5;
  stroke-linecap: round;
}

/* Head and handle are both silhouettes rather than a shape plus a line: a stroked
   shaft next to a filled head reads as two different drawings at this size. */
.notfound-outcrop .hammer {
  fill: var(--ink-2);
}

.notfound-outcrop .puzzle {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 22px;
  text-anchor: middle;
  fill: var(--ink-2);
}

.notfound-page h1 {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 2.2rem;
  font-weight: 400;
  margin: 0.5rem 0 0.75rem;
  color: var(--ink);
}

.notfound-page p {
  font-size: 1.05rem;
  color: var(--ink-2);
  margin: 0 0 1.5rem;
}

.notfound-home {
  color: var(--accent);
}

@media (max-width: 600px) {
  .notfound-page h1 { font-size: 1.7rem; }
}

/* ============================================================
   Cookies / transparency page + reusable neologism tooltip
   ============================================================ */

.cookies-page {
  padding: 1rem 0.5rem 2rem;
  max-width: 820px;
  margin: 0 auto;
}

.cookies-page h1 {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 2.4rem;
  font-weight: 400;
  margin: 0 0 0.5rem;
  color: var(--ink);
}

.cookies-page > p {
  font-size: 1.05rem;
  color: var(--ink-2);
  margin: 0 0 1.5rem;
}

.cookies-section {
  margin: 1.5rem 0;
  padding: 1.2rem 1.4rem;
  background: var(--ground-3);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0;
}

.cookies-section h2 {
  font-family: 'GFS Didot', 'Cormorant Garamond', Georgia, serif;
  font-size: 1.5rem;
  font-weight: 400;
  margin: 0 0 0.6rem;
  color: var(--ink);
}

.cookies-section p {
  margin: 0.5rem 0;
  color: var(--ink);
  line-height: 1.55;
}

.cookies-entry-list {
  list-style: none;
  padding: 0;
  margin: 0.6rem 0 0;
}

.cookies-entry-list li {
  padding: 0.5rem 0;
  border-bottom: 1px solid #f0e9da;
  color: var(--ink);
  line-height: 1.5;
}

.cookies-entry-list li:last-child {
  border-bottom: none;
}

.cookies-entry-list code {
  background: var(--ground-2);
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.92em;
  color: var(--ink-2);
}

.cookies-code-ref {
  display: inline-block;
  margin-left: 0.4rem;
  font-size: 0.85rem;
  color: var(--ink-3);
  text-decoration: none;
  font-family: monospace;
  background: var(--ground-3);
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  white-space: nowrap;
}

.cookies-code-ref:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* Toggle switch + state */
.cookies-manage {
  --manage-top: #f5ead2;
  --manage-bottom: #ece0c2;
  background: linear-gradient(180deg, var(--manage-top) 0%, var(--manage-bottom) 100%);
  border-left-color: #5e8c41;
}

:root[data-theme="dark"] .cookies-manage {
  --manage-top: var(--ground-3);
  --manage-bottom: var(--ground-2);
}

.cookies-toggle-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 0.8rem 0 0.4rem;
  flex-wrap: wrap;
}

.cookies-toggle {
  position: relative;
  display: inline-block;
  width: 56px;
  height: 30px;
  flex: 0 0 auto;
}

.cookies-toggle input {
  opacity: 0;
  width: 0;
  height: 0;
}

.cookies-toggle-slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: var(--rule-2);
  border-radius: 30px;
  transition: background 0.25s ease;
}

.cookies-toggle-slider::before {
  content: "";
  position: absolute;
  width: 24px;
  height: 24px;
  left: 3px;
  bottom: 3px;
  background: var(--ground-3);
  border-radius: 50%;
  transition: transform 0.25s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.cookies-toggle input:checked + .cookies-toggle-slider {
  background: #5e8c41;
}

.cookies-toggle input:checked + .cookies-toggle-slider::before {
  transform: translateX(26px);
}

.cookies-toggle input:focus + .cookies-toggle-slider {
  box-shadow: 0 0 0 3px rgba(94, 140, 65, 0.4);
}

.cookies-toggle-text {
  font-size: 1rem;
  color: var(--ink);
}

.cookies-state-on {
  color: #5e8c41;
  font-weight: 700;
  letter-spacing: 0.05em;
}

.cookies-state-off {
  color: #b04540;
  font-weight: 700;
  letter-spacing: 0.05em;
}

:lang(el) .cookies-state-on,
:lang(el) .cookies-state-off,
:lang(grc) .cookies-state-on,
:lang(grc) .cookies-state-off {
  letter-spacing: 0.02em;
}

.cookies-saved-msg {
  color: #5e8c41;
  font-style: italic;
  margin: 0.4rem 0 0;
  font-size: 0.95rem;
}

/* Neologism tooltip — reusable across the site for coined Greek words.
   Suppressed in English: the underlying word in en (e.g. "Cookies") IS
   already the international term, so no tooltip / affordance is needed. */
.neologism {
  position: relative;
  display: inline-block;
  border-bottom: 1px dotted var(--rule-2);
  cursor: help;
}

.neologism:focus {
  outline: 2px solid #b8956a;
  outline-offset: 2px;
  border-radius: 2px;
}

:lang(en) .neologism {
  border-bottom: none;
  cursor: inherit;
}

:lang(en) .neologism:focus {
  outline: none;
}

:lang(en) .neologism-tip {
  display: none;
}

.neologism-tip {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 320px;
  background: var(--ink);
  color: #faf3e6;
  padding: 0.6rem 0.9rem;
  border-radius: 0;
  font-size: 0.88rem;
  font-weight: 400;
  font-style: normal;
  line-height: 1.4;
  letter-spacing: normal;
  text-transform: none;
  z-index: 50;
  transition: opacity 0.2s ease, visibility 0.2s ease;
  pointer-events: none;
  text-align: left;
  white-space: normal;
}

.neologism-tip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--ink);
}

.neologism:hover .neologism-tip,
.neologism:focus .neologism-tip {
  visibility: visible;
  opacity: 1;
}

@media (max-width: 720px) {
  .cookies-page h1 { font-size: 1.9rem; }
  .cookies-section { padding: 1rem 0.9rem; }
  .cookies-section h2 { font-size: 1.25rem; }
  .neologism-tip {
    max-width: 240px;
    font-size: 0.82rem;
  }
}

/* --- Sharing --- */

/* Page-level share button in the header */
.header-share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px;
  border-radius: 6px;
  color: #fff;
  transition: background 0.2s ease, transform 0.15s ease;
}

.header-share-btn svg {
  width: 22px;
  height: 22px;
  display: block;
}

.header-share-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  transform: translateY(-1px);
}

/* Share button injected into the lightGallery toolbar */
.lg-share-btn {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  vertical-align: top;
  width: 50px;
  height: 47px;
  padding: 0;
  color: #fff;
}

.lg-share-btn svg {
  width: 22px;
  height: 22px;
}

/* TTS player — reads the description (and etymology) aloud. Sits just above the
   .description-text block; hidden for unsupported langs. Idle, it is a compact
   "Listen" pill; pressing it expands the .tts-transport row (and hides the pill).*/
.tts-player {
  display: flex;
  align-items: center;
  margin-bottom: 0.9rem;
}

/* Collapsed entry point: the "Listen" pill (speaker icon + label). */
.tts-listen {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  align-self: flex-start;
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--ground-3);
  color: var(--accent);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

/* Hover values are tokens rather than declarations on a dark-theme selector, so
   the theme does not change how specific the rule is. See .tts-ctl:hover. */
.tts-listen {
  --listen-hover-bg: #f0e3cb;
  --listen-hover-border: #c2a472;
}

:root[data-theme="dark"] .tts-listen {
  --listen-hover-bg: var(--ground-2);
  --listen-hover-border: var(--accent);
}

.tts-listen:hover {
  background: var(--listen-hover-bg);
  border-color: var(--listen-hover-border);
}

.tts-listen .tts-icon {
  display: inline-flex;
}

.tts-listen .tts-icon svg {
  width: 18px;
  height: 18px;
}

/* Expanded transport row, shown once playback starts. */
.tts-transport {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--ground-3);
  color: var(--accent);
}

/* Show one form or the other: pill while idle, transport while active. */
.tts-player:not(.is-active) .tts-transport { display: none; }
.tts-player.is-active .tts-listen { display: none; }

.tts-ctl {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

/* A token, not a declaration under a dark-theme selector: overriding the
   declaration would make the dark rule more specific than the light one, and
   the two themes would no longer lose to the same rules. */
.tts-ctl {
  --ctl-hover-bg: #ecdcbf;
}

:root[data-theme="dark"] .tts-ctl {
  --ctl-hover-bg: var(--ground-2);
}

.tts-ctl:hover {
  background: var(--ctl-hover-bg);
}

.tts-ctl svg {
  width: 20px;
  height: 20px;
}

/* Speed button — shows the current rate as text (e.g. "1.25×"); tapping it
   cycles through the preset rates. */
.tts-rate {
  width: auto;
  min-width: 2.9rem;
  padding: 0 0.5rem;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

/* Seek bar — a slim range input styled in the warm palette. */
.tts-seek {
  flex: 1 1 120px;
  min-width: 90px;
  height: 4px;
  margin: 0 0.2rem;
  -webkit-appearance: none;
  appearance: none;
  background: var(--ground-2);
  border-radius: 999px;
  cursor: pointer;
  outline: none;
}

.tts-seek::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: transparent;
}

.tts-seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--rule);
  cursor: pointer;
}

.tts-seek::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: var(--ground-2);
}

.tts-seek::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--rule);
  cursor: pointer;
}

/* Toast confirming a link was copied */
.share-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  background: #333;
  color: #fff;
  padding: 0.6rem 1.1rem;
  border-radius: 8px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
  font-size: 0.95rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  z-index: 10000;
}

.share-toast-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Persistent, prominent highlight of a specimen deep-linked via #sample-<id>.
   An intro pulse grabs attention, then the steady outline + glow below remain
   until the user navigates to a different specimen. */
.sample-box.sample-highlight {
  position: relative;
  z-index: 3;
  border-radius: 8px;
  outline: 3px solid #b8956a;
  box-shadow: 0 0 18px 4px rgba(184, 149, 106, 0.55);
  animation: sample-pulse 2.4s ease-in-out;
}

@keyframes sample-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(184, 149, 106, 0); transform: scale(1); }
  8%   { box-shadow: 0 0 0 6px rgba(184, 149, 106, 1), 0 0 26px 10px rgba(184, 149, 106, 0.85); transform: scale(1.04); }
  28%  { box-shadow: 0 0 0 6px rgba(184, 149, 106, 0.35), 0 0 26px 10px rgba(184, 149, 106, 0.25); transform: scale(1); }
  48%  { box-shadow: 0 0 0 6px rgba(184, 149, 106, 1), 0 0 26px 10px rgba(184, 149, 106, 0.85); transform: scale(1.04); }
  68%  { box-shadow: 0 0 0 6px rgba(184, 149, 106, 0.35), 0 0 26px 10px rgba(184, 149, 106, 0.25); transform: scale(1); }
  88%  { box-shadow: 0 0 0 6px rgba(184, 149, 106, 1), 0 0 26px 10px rgba(184, 149, 106, 0.85); transform: scale(1.03); }
  100% { box-shadow: 0 0 0 0 rgba(184, 149, 106, 0); transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .sample-box.sample-highlight {
    animation: none;
    outline: 4px solid #b8956a;
    box-shadow: 0 0 22px 6px rgba(184, 149, 106, 0.8);
  }
  .header-share-btn:hover { transform: none; }
}

/* ============================================================
   Deep time
   ============================================================ */

/* The International Chronostratigraphic Chart, at true linear scale, with the
   span this page's specimens come from bracketed on it. Colours are the ICS's
   own values from jsondata/ics_periods.json — not chosen here, which is the
   reason they are trustworthy as data. */
.deep-time {
  margin: 1.6rem 0 0;
  max-width: 640px;
}

.deep-time-caption {
  display: block;
  margin: 0 0 0.5rem;
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: 0.11em;
  text-transform: var(--caps);
  color: var(--ink-3);
}

.deep-time-bar {
  position: relative;
  display: flex;
  height: 26px;
  border: 1px solid var(--rule-2);
  overflow: hidden;
}

/* The band's own ICS colour, written onto it as --band by deep_time.html. The
   dark palette takes it as a shade, as the specimen cards and the vertical rail
   do: the commission mixed these for a white chart, and raw on a near-black page
   the bar is a row of lamps. */
.deep-time-period {
  position: relative;
  min-width: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--band);
}

:root[data-theme="dark"] .deep-time-period {
  background: color-mix(in srgb, var(--band) 34%, var(--ground-2));
}

/* The abbreviation is emitted only where its period is wide enough to hold it
   (see deep_time.html), so narrow periods stay honest rather than being widened
   to fit a label. */
.deep-time-period i {
  font-family: var(--data);
  font-size: 9px;
  font-style: normal;
  letter-spacing: 0.04em;
  color: var(--band-ink, rgba(0, 0, 0, 0.68));
  white-space: nowrap;
  padding: 0 2px;
}

/* Once the band is a shade, the ink picked to read on the bright original does
   not read on it; every shaded band is dark, so one light ink serves them all. */
:root[data-theme="dark"] .deep-time-period i {
  color: var(--ink);
}

/* The span is outlined, not filled. A translucent wash over it dimmed the one
   band the reader is being pointed at — washing out both the ICS colour and the
   name printed on it — which is backwards. */
.deep-time-span {
  position: absolute;
  top: -1px;
  bottom: -1px;
  min-width: 2px;
  border: 2px solid var(--ink);
  background: transparent;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.55);
  pointer-events: none;
}

.deep-time-scale {
  display: flex;
  /* Narrow columns wrap the middle item rather than pushing the right-hand end off
     the bar. */
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-top: 5px;
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: var(--caps);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.deep-time-here {
  color: var(--ink);
  font-weight: 700;
}

/* ============================================================
   Homepage
   ============================================================ */

.section-heading {
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  margin: 0 0 1.2rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule-2);
}

.catalogued-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 16px;
  justify-content: initial;
  padding: 0;
}

.catalogued-grid .sample-box { text-decoration: none; }

/* The random sample. It was a centred image under a bare heading; it is now a
   plate like every other specimen on the site, so it reads as part of the
   collection rather than as a widget. */
#random-sample-row > div {
  display: block;
}

#random-sample-row h2 {
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  margin: 0 0 1.2rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule-2);
  text-align: left;
}

#random-sample-row h2 a { text-decoration: none; }

#τυχαίο-δείγμα-σύνδεσμος {
  display: block;
  max-width: 420px;
  background: var(--plate);
  border: 1px solid var(--rule-2);
  box-shadow: var(--lift);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

#τυχαίο-δείγμα-σύνδεσμος:hover {
  transform: translateY(-3px);
  box-shadow: var(--lift-2);
}

#τυχαίο-δείγμα-εικόνα {
  width: 100%;
  margin: 0;
  display: block;
}

/* ── Drawer icons and the palette control ───────────────────────────────── */
.drawer-nav a,
.drawer-theme {
  display: flex;
  align-items: center;
  gap: 10px;
}

.drawer-icon {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

.drawer-theme {
  width: 100%;
  margin-top: 0.3em;
  padding: 0.5em;
  background: none;
  border: 0;
  border-top: 1px solid var(--rule);
  border-radius: 0;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--data);
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: var(--caps);
  text-align: left;
}

.drawer-theme:hover { background: var(--ground-2); }

.drawer-tree h3 {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* The tree heading's icon is the one drawer mark that is a label rather than a
   link, so it takes the muted colour of the heading it sits in. */
.drawer-tree h3 .drawer-icon {
  width: 14px;
  height: 14px;
  flex-basis: 14px;
}

/* ── Locality specification ─────────────────────────────────────────────────
   Age, formation, environment and the rest were a bulleted list, which reads as
   prose that happens to be indented. They are field measurements, so they are
   set as a table: labels in the data voice on the left, values in the reading
   face on the right, one hairline between rows. */
.locality-spec {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(120px, 200px) minmax(0, 1fr);
  border-top: 1px solid var(--rule-2);
}

.locality-spec dt {
  padding: 11px 16px 11px 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--data);
  font-size: 10.5px;
  letter-spacing: 0.11em;
  text-transform: var(--caps);
  color: var(--ink-3);
}

.locality-spec dd {
  margin: 0;
  padding: 11px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}

.locality-spec dd.locality-spec-num {
  font-family: var(--data);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

@media (max-width: 600px) {
  .locality-spec { grid-template-columns: 1fr; }
  .locality-spec dt { padding-bottom: 2px; border-bottom: 0; }
  .locality-spec dd { padding-top: 0; }
}

/* ============================================================
   Locality page
   ============================================================ */

/* The breakout below is 100vw wide, and on a page with a classic scrollbar that
   is a few pixels more than the visible area. `clip` absorbs the overhang; it is
   not `hidden`, which would make the body a scroll container and take sticky and
   fixed positioning down with it. */
body.locality-page {
  overflow-x: clip;
}

/* ── The hero ───────────────────────────────────────────────────────────────
   The paleo-environment reconstruction is the only picture on the page that is
   about the place rather than a specimen from it, and it was being shown at
   710px in the middle of the reading column with the globe stranded beside it.
   It is now a band the full width of the viewport, with the name set on it and
   the interval's ICS colour along the bottom edge — the same rule that used to
   sit under the heading, now the waterline of the sea the locality was. */
.locality-page .locality-hero {
  position: relative;
  padding: 0;
  /* Flush under the header: the wrapper's 20px and main's 20px are given back, so
     the band starts where the header ends rather than after a sliver of ground. */
  margin: -40px 0 2.4rem;
  /* Out of the 1300px column to the viewport edges. 50% is half the containing
     block, 50vw half the viewport, so the difference is exactly the inset. */
  margin-inline: calc(50% - 50vw);
  overflow: hidden;
  background: var(--ink);
  box-shadow: 0 1px 0 var(--rule-2);
}

.locality-hero-media {
  display: block;
}

.locality-hero-media img {
  display: block;
  /* The global `img { margin: 10px auto }` would leave a strip of the hero's own
     background above and below the band. */
  margin: 0;
  width: 100%;
  /* The band crops, so the two things that decide the crop are how deep it is and
     where in the picture it is taken from.

     Deep enough: the height follows the viewport's width rather than its height,
     so the band keeps roughly the same slice of the picture on a laptop and on a
     wide monitor instead of cropping harder the wider the screen gets. The vh
     ceiling stops it from filling a short window, the px floor from collapsing on
     a phone.

     Taken above centre: about half these reconstructions are landscapes whose
     horizon and distant land sit in the upper third, and that band is the whole
     scene — cropping it away leaves an anonymous stretch of water. The rest are
     open water, where the interest is in the seabed lower down, so the anchor is
     only as high as it has to be to keep every horizon in frame. */
  height: clamp(300px, 36vw, 66vh);
  object-fit: cover;
  object-position: center 38%;
}

/* The name sits on the picture, so it needs its own ground: a scrim dark enough
   to carry parchment-coloured Didot over water, sky or rock alike, fading out
   before it reaches the middle of the image. */
.locality-hero-plate {
  position: absolute;
  inset: auto 0 0 0;
  padding: 5rem 0 1.5rem;
  background: linear-gradient(to top,
              rgba(8, 6, 4, 0.86) 0%,
              rgba(8, 6, 4, 0.55) 42%,
              rgba(8, 6, 4, 0) 100%);
  pointer-events: none;
}

/* Aligned with the reading column beneath it: the wrapper's 20px, main's 8px and
   the section's 8px, added up. */
.locality-hero-plate h1 {
  max-width: 1300px;
  margin: 0 auto;
  padding-inline: 36px;
  color: var(--on-dark);
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.6);
}

/* ── The body ───────────────────────────────────────────────────────────────
   Four blocks — the chart, the specification, the account and the globe — whose
   reading order is not the same in the two layouts, so all four are direct
   children of one grid and it places them.

   Narrow, they read: globe, chart, specification, account. The globe goes
   straight under the picture because on a phone the first question about a place
   is where it is, and a full-width map answers it before any of the numbers do.

   Wide, the chart and the specification span both columns and the account and
   the globe sit side by side. The description used to run at its 66ch measure
   down the left of a 1300px page with nothing to its right: the measure was
   right, the second column was what was missing. */
.locality-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: 2.2rem;
  align-items: start;
}

.locality-globe { order: 1; }
.locality-body .deep-time { order: 2; }
.locality-page .locality-spec { order: 3; }
.locality-prose { order: 4; }

@media (min-width: 1000px) {
  .locality-body {
    grid-template-columns: minmax(0, 66ch) minmax(300px, 1fr);
    column-gap: 3.5rem;
  }

  /* Explicit placement, so `order` no longer has anything to say. */
  .locality-body .deep-time { grid-area: 1 / 1 / 2 / -1; }
  .locality-page .locality-spec { grid-area: 2 / 1 / 3 / -1; }
  .locality-prose { grid-area: 3 / 1 / 4 / 2; }
  .locality-globe { grid-area: 3 / 2 / 4 / -1; }
}

/* A linear scale is worth more the wider it is drawn: 640px was leaving the
   epochs unlabelled. */
.locality-body .deep-time {
  max-width: none;
  margin: 0;
}

.locality-body .deep-time-bar {
  height: 32px;
}

.locality-prose {
  min-width: 0;
}

/* The Listen pill is inserted at the top of this column by scripts/tts.js. It
   used to be laid against the underside of the table's last rule; the column
   now starts clear of it. */
.locality-prose .tts-player {
  margin-top: 0;
  margin-bottom: 1.2rem;
}

/* Stacked, the plate would otherwise run the whole width of a tablet and give a
   locator map four hundred pixels of height it has no use for. */
@media (max-width: 999px) {
  .locality-globe {
    max-width: 520px;
  }
}

.locality-globe {
  display: block;
  min-width: 0;
  text-decoration: none;
  background: var(--ground-2);
  border: 1px solid var(--rule-2);
  box-shadow: var(--lift);
  overflow: hidden;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

.locality-globe:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-2);
}

.locality-globe img {
  display: block;
  margin: 0;
  width: 100%;
  height: auto;
}

.locality-globe-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 14px;
  border-top: 1px solid var(--rule);
  font-family: var(--data);
  font-size: 10.5px;
  letter-spacing: 0.11em;
  text-transform: var(--caps);
  color: var(--ink-3);
  transition: color 0.2s ease;
}

.locality-globe:hover .locality-globe-label {
  color: var(--ink);
}

.locality-globe-arrow {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.2s var(--ease);
}

.locality-globe:hover .locality-globe-arrow {
  transform: translateX(3px);
}

/* An explanatory diagram inside the account (currently only the longshore drift
   panel at Chapel St Leonards). */
.locality-diagram {
  margin: 1.8rem 0 0;
}

.locality-diagram img {
  display: block;
  margin: 0;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule-2);
  background: var(--plate);
}

.locality-diagram figcaption {
  margin-top: 0.7rem;
  color: var(--ink-2);
  font-size: 0.92rem;
}

/* Wide enough for it, the specification reads two measurements to a line rather
   than a single column with half the page empty beside it. The hairline runs the
   whole width, so the rows still read as rows. */
@media (min-width: 1150px) {
  .locality-page .locality-spec {
    grid-template-columns:
      minmax(110px, 180px) minmax(0, 1fr)
      minmax(110px, 180px) minmax(0, 1fr);
  }

  .locality-page .locality-spec dd {
    padding-right: 2.5rem;
  }

  .locality-page .locality-spec dd:nth-of-type(2n) {
    padding-right: 0;
  }
}

@media (max-width: 720px) {
  /* .main-section-wrapper clips its overflow on small screens, so the viewport
     breakout cannot reach past it; the wrapper's own 12px and main's 8px are
     given back instead, which puts the band edge to edge all the same. */
  .locality-page .locality-hero {
    /* A little ground is kept above the band on a phone: the search field spans the
       whole header there, and its underside against the picture reads as cramped. */
    margin-top: -28px;
    margin-inline: -20px; /* the wrapper's 12px here, plus main's 8px */
  }

  .locality-hero-plate {
    padding: 3.5rem 0 1.1rem;
  }

  .locality-hero-plate h1 {
    padding-inline: 20px;
  }
}

/* Marks inside the lightbox caption. Same stroked style as the drawer and plate
   icons, sized to sit on the caption's baseline. */
.meta-icon {
  width: 13px;
  height: 13px;
  display: inline-block;
  vertical-align: -2px;
  margin-right: 3px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── Small screens: the taxon page ──────────────────────────────────────────
   The illustration and the reading column are a two-column grid, and it was not
   collapsing: at 390px the picture kept its 300px track and left the text about
   ninety pixels, one word per line, with the page overflowing to 481px and
   scrolling sideways. */
@media (max-width: 720px) {
  .taxon-story {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  .story-visuals {
    max-width: 320px;
    margin-inline: auto;
  }

  .taxon-story .prose,
  .description-text p,
  .etymology-text p {
    max-width: none;
  }
}

/* Nothing may exceed the viewport width. The listen button was the widest
   offender at 449px on a 390px screen; this keeps any future one in check
   rather than waiting for it to be noticed.

   `clip`, not `hidden`: overflow is a pair, and a `hidden` on one axis forces
   the other from `visible` to `auto`. That turned this wrapper into a scroll
   box — 173px tall on a phone, holding a 12,000px journal entry — and since the
   document itself then had nothing to scroll, the header and the footer stayed
   put while the article moved between them. `clip` is allowed to sit beside
   `visible`, so it bounds the width without any of that. */
@media (max-width: 720px) {
  .main-section-wrapper {
    padding-inline: 12px;
    overflow-x: clip;
  }

  .tts-listen,
  .tts-player {
    max-width: 100%;
    flex-wrap: wrap;
  }
}

/* A locality with a single approximate age rather than a range. Drawn as the
   line it is: widening it into a box would claim a precision the data does not
   have, and five localities plus the taxa that only occur at them are in this
   position. */
.deep-time-span-point {
  width: 0 !important;
  border-left-width: 3px;
  border-right-width: 0;
}
