/* =========================================================================
   vondrlik.com — one stylesheet
   tokens · base · type · layout · components · language · motion · print
   ========================================================================= */

/* ---------- type ------------------------------------------------------- */
/* IBM Plex Sans, in two widths of one super-family.
   The condensed cut is the voice of the site: headings, the index, labels,
   captions, the CV. Normal width is reserved for running prose, where a
   condensed face gets tiring over several paragraphs.
   Plex was drawn with unusually careful Central European diacritics, which
   is the reason it survives the Czech half of this site intact.
   unicode-range means the Czech files only download when Czech is rendered. */

@font-face {
  font-family: 'PlexCond';
  font-style: normal;
  font-weight: 200;
  font-display: swap;
  src: url('../fonts/plex-cond-200-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'PlexCond';
  font-style: normal;
  font-weight: 200;
  font-display: swap;
  src: url('../fonts/plex-cond-200-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'PlexCond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/plex-cond-300-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'PlexCond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/plex-cond-300-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Plex';
  font-style: normal;
  font-weight: 200 500;
  font-display: swap;
  src: url('../fonts/plex-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Plex';
  font-style: normal;
  font-weight: 200 500;
  font-display: swap;
  src: url('../fonts/plex-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- tokens ------------------------------------------------------ */

:root {
  /* paper and ink */
  --paper: #faf8f3;
  --paper-warm: #f2ede3;
  --ink: #1c1a17;
  --ink-soft: #6b6255;
  --oak: #c9b7a0;        /* hairlines and decorative strokes only, never text */
  --oak-deep: #94826a;   /* meaningful graphics: 3.5:1 on paper */
  --oak-faint: #e3d9cb;
  --walnut: #6e5a46;
  --moss: #3f4a3e;
  --amber: #ed8b00;      /* food-trip routes: deliberately not a place-marker.
                            Kept fully saturated — a muted orange sits at the same
                            lightness as the coastlines and disappears into them. */

  /* type — one super-family, two widths */
  --display: 'PlexCond', 'Helvetica Neue', Arial, sans-serif;  /* the site voice */
  --text: 'Plex', 'Helvetica Neue', Arial, sans-serif;          /* running prose */

  --s--1: clamp(0.76rem, 0.74rem + 0.12vw, 0.83rem);
  --s-0: clamp(1rem, 0.96rem + 0.2vw, 1.12rem);
  --s-1: clamp(1.25rem, 1.15rem + 0.5vw, 1.6rem);
  --s-2: clamp(1.6rem, 1.35rem + 1.2vw, 2.4rem);
  --s-3: clamp(2.1rem, 1.6rem + 2.4vw, 3.6rem);
  --s-4: clamp(2.8rem, 1.7rem + 5vw, 6rem);
  --s-5: clamp(3.4rem, 1.4rem + 8vw, 8.5rem);

  --label: 0.72rem;
  --track-label: 0.16em;

  /* space */
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --gap: clamp(1rem, 2.2vw, 2.25rem);
  --maxw: 1320px;
  --measure: 62ch;
  --rhythm: clamp(4rem, 11vh, 9rem);

  /* motion */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 0.52s;
}

/* ---------- reset ------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-0);
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; }
ul, ol { list-style: none; padding: 0; }

:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 4px;
}

::selection { background: var(--oak-faint); color: var(--ink); }

/* ---------- typography -------------------------------------------------- */

.display {
  font-family: var(--display);
  font-weight: 200;
  /* 1.04 rather than tighter: Czech stacks carons above the cap line, and a
     two-line heading must not let them meet the descenders of the line above. */
  line-height: 1.04;
  letter-spacing: -0.008em;
  text-wrap: balance;
}

/* Below the two largest steps, ExtraLight starts to disappear on paper. */
.d-m,
.d-s,
.d-xs { font-weight: 300; letter-spacing: -0.004em; }

.d-xl { font-size: var(--s-5); }
.d-l  { font-size: var(--s-4); }
.d-m  { font-size: var(--s-3); }
.d-s  { font-size: var(--s-2); }
.d-xs { font-size: var(--s-1); line-height: 1.2; }

.label {
  font-family: var(--text);
  font-size: var(--label);
  font-weight: 450;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.4;
}

.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.prose {
  max-width: var(--measure);
  font-family: var(--text);
  letter-spacing: 0.002em;
}
.prose p + p { margin-top: 1.25em; }
.prose em { font-style: italic; font-weight: 400; }

.lede {
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-1);
  line-height: 1.4;
  max-width: 34ch;
  text-wrap: pretty;
}

.soft { color: var(--ink-soft); }
.hairline {
  border: 0;
  border-top: 1px solid var(--oak-faint);
}

/* the templated-value hint: visibly a slot, never mistaken for a fact */
.slot {
  color: var(--walnut);
  border-bottom: 1px dashed var(--oak);
  padding-bottom: 1px;
}

/* ---------- layout ------------------------------------------------------ */

.wrap {
  width: min(100% - (var(--gutter) * 2), var(--maxw));
  margin-inline: auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gap);
}

.section { padding-block: var(--rhythm); }
.section--tight { padding-block: calc(var(--rhythm) * 0.55); }

/* asymmetric placements — the Japandi off-grid */
.col-a { grid-column: 2 / span 6; }
.col-b { grid-column: 8 / span 4; }
.col-c { grid-column: 2 / span 5; }
.col-d { grid-column: 7 / span 5; }
.col-full { grid-column: 2 / -2; }
.col-mid { grid-column: 2 / -2; }   /* the content box, same as everything else */

/* The cover's hero occupies columns 2 to 11, and that box is the content width
   for the whole site. Anything placed directly in a .wrap — the index list, the
   map, a proof sheet, the pager — is put on the same grid so it cannot run wider
   than the heading above it. Only the column gap is inherited; the row gap stays
   zero so vertical rhythm is still set by the elements themselves. */
.wrap:not(.grid) {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gap);
  row-gap: 0;
}
.wrap:not(.grid) > * { grid-column: 2 / -2; }

@media (max-width: 900px) {
  .col-a, .col-b, .col-c, .col-d, .col-mid { grid-column: 1 / -1; }
  /* one column of inset is a large share of a phone screen, so below 900px
     everything uses the full gutter width instead */
  .col-full, .wrap:not(.grid) > * { grid-column: 1 / -1; }
}

.stack > * + * { margin-top: var(--flow, 1.5rem); }

/* ---------- header, wordmark, the + menu -------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  z-index: 100;
}
.skip:focus { left: 0; }

/* The bar is fixed, opaque, and sits above the menu panel. It carries the same
   paper as the rest of the site, so content passes behind it rather than
   through it. */
.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 70;
  padding-block: clamp(0.8rem, 2vw, 1.5rem);
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color 0.35s var(--ease);
}
/* The bar spans the window so its background and hairline reach both edges, but
   its contents sit on the page grid — the wordmark and the menu button line up
   with the columns every section uses, and cannot drift from them. */
.topbar-in { align-items: center; }
.topbar .wordmark { grid-column: 2 / span 6; }
.topbar .menu-btn { grid-column: 11 / -2; justify-self: end; }

/* Below 900px the page drops the one-column inset and uses the full gutter, so
   the bar has to follow it. This has to sit after the rules above, not in the
   layout section's media query, or source order beats the media query. */
@media (max-width: 900px) {
  .topbar .wordmark { grid-column: 1 / span 8; }
  .topbar .menu-btn { grid-column: -2 / -1; }
}

/* Once something has scrolled underneath, a hairline says where the bar ends.
   At the top of the page there is nothing to separate, so there is no line. */
.topbar[data-scrolled='true'] { border-bottom-color: var(--oak-faint); }
/* Against the open menu the bar and the panel are one surface. */
.topbar[data-menu='true'] { border-bottom-color: transparent; }

.wordmark {
  font-family: var(--display);
  font-size: var(--s-1);
  font-weight: 300;
  letter-spacing: 0.02em;
  text-decoration: none;
}
.wordmark span { display: block; }

/* The cover's hero already carries the name, so the bar holds it back until
   there is something scrolled behind it, or the menu is open. */
.wordmark--deferred {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}
.topbar[data-scrolled='true'] .wordmark--deferred,
.topbar[data-menu='true'] .wordmark--deferred {
  opacity: 1;
  pointer-events: auto;
}

/* the menu button */
.menu-btn {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  /* the 18px icon sits centred in a 44px hit area, so the box is pulled out by
     the 13px of padding on its right — that lines the icon itself up with the
     content edge, the way the wordmark's glyphs do on the left */
  margin-right: -13px;
  border-radius: 50%;
}

/* three lines that fold into a cross */
.bars,
.bars::before,
.bars::after {
  display: block;
  width: 18px;
  height: 1px;
  background: var(--ink);
  transition: transform 0.3s var(--ease), background 0.2s var(--ease);
}
.bars { position: relative; }
.bars::before { content: ''; position: absolute; left: 0; top: -5px; }
.bars::after { content: ''; position: absolute; left: 0; top: 5px; }

.menu-btn[aria-expanded='true'] .bars { background: transparent; }
.menu-btn[aria-expanded='true'] .bars::before { transform: translateY(5px) rotate(45deg); }
.menu-btn[aria-expanded='true'] .bars::after { transform: translateY(-5px) rotate(-45deg); }

/* ---------- prev / next pager ------------------------------------------- */

.pager-wrap { padding-top: clamp(4.5rem, 12vh, 7rem); }

.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: clamp(0.5rem, 1.2vw, 0.9rem);
  border-bottom: 1px solid var(--oak-faint);
}
.pager-link {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--ink-soft);
  font-family: var(--text);
  font-size: var(--label);
  font-weight: 450;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: color 0.3s var(--ease);
  min-height: 44px;
}
.pager-link:hover,
.pager-link:focus-visible { color: var(--ink); }
.pager-link svg {
  width: 18px;
  height: 8px;
  flex: none;
  transition: transform 0.3s var(--ease);
}
.pager-link svg path { stroke: currentColor; stroke-width: 1; fill: none; }
.pager-prev:hover svg,
.pager-prev:focus-visible svg { transform: translateX(-4px); }
.pager-next:hover svg,
.pager-next:focus-visible svg { transform: translateX(4px); }
.pager-link .num { color: var(--moss); }
.pager-next { text-align: right; margin-left: auto; }

/* Below this the titles crowd the arrows, and the numbers carry it: on a
   cookbook index the number is the name. */
@media (max-width: 460px) {
  .pager-t { display: none; }
}
@media (min-width: 461px) {
  /* let the two links share the row and only clip when they genuinely collide */
  .pager-link { min-width: 0; }
  .pager-t {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* the unfolding panel */
.panel {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: var(--paper);
  display: grid;
  /* `safe` keeps the first row reachable when the list is taller than the
     viewport; plain `center` would clip it off the top with no way to scroll. */
  align-content: safe center;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(5.5rem, var(--rhythm), 9rem) var(--gutter) clamp(2.5rem, 6vh, 5rem);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 0.32s var(--ease), transform 0.32s var(--ease),
    visibility 0s linear 0.32s;
}
.panel[data-open='true'] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.panel ol { max-width: 46rem; margin-inline: auto; width: 100%; }

/* On short screens the seven rows must still fit without scrolling. */
@media (max-height: 800px) {
  .panel .index-link { padding-block: clamp(0.5rem, 1.5vh, 1rem); }
  .panel .index-link .t { font-size: var(--s-1); }
}
/* Below this, centring cannot win: align to the top and let the panel scroll. */
@media (max-height: 640px) {
  .panel { align-content: start; }
}

/* ---------- the cookbook index ------------------------------------------ */

.index { width: 100%; }

.index-row {
  border-top: 1px solid var(--oak-faint);
}
.index-row:last-child { border-bottom: 1px solid var(--oak-faint); }

.index-link {
  display: grid;
  grid-template-columns: 3.5rem 1fr auto;
  align-items: baseline;
  gap: clamp(0.75rem, 2vw, 2rem);
  padding-block: clamp(0.9rem, 2vw, 1.4rem);
  text-decoration: none;
  transition: color 0.3s var(--ease);
}
.index-link .n {
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  transition: color 0.3s var(--ease);
}
.index-link .t {
  font-family: var(--display);
  font-size: var(--s-2);
  font-weight: 300;
  line-height: 1.1;
  transition: transform 0.36s var(--ease);
  transform-origin: left;
}
.index-link .d {
  font-size: var(--s--1);
  color: var(--ink-soft);
  text-align: right;
  max-width: 22ch;
  opacity: 0;
  transition: opacity 0.36s var(--ease);
}
.index-link:hover .t,
.index-link:focus-visible .t { transform: translateX(8px); }
.index-link:hover .n,
.index-link:focus-visible .n { color: var(--moss); }
.index-link:hover .d,
.index-link:focus-visible .d { opacity: 1; }

@media (max-width: 760px) {
  .index-link { grid-template-columns: 2.6rem 1fr; }
  .index-link .d { display: none; }
}

/* ---------- editorial cards --------------------------------------------- */

.card {
  background: var(--paper-warm);
  padding: clamp(1.4rem, 2.6vw, 2.2rem);
  display: grid;
  gap: 0.7rem;
  align-content: start;
}
.card .label { color: var(--walnut); }
.card p { font-size: var(--s--1); line-height: 1.6; }
.card--outline {
  background: none;
  border: 1px solid var(--oak-faint);
}

/* ---------- section heads ----------------------------------------------- */

.sec-head {
  display: grid;
  gap: 0.9rem;
  margin-bottom: clamp(2rem, 5vw, 4rem);
}
.sec-head .n {
  font-size: var(--label);
  letter-spacing: var(--track-label);
  color: var(--moss);
}

/* ---------- pull quote / manifesto -------------------------------------- */

.pull {
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-2);
  line-height: 1.25;
  max-width: 24ch;
  text-wrap: pretty;
}
.pull::before { content: '\201C'; margin-left: -0.4em; }
.pull::after { content: '\201D'; }

.manifesto { counter-reset: m; }
.manifesto li {
  counter-increment: m;
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 1rem;
  padding-block: clamp(0.9rem, 2vw, 1.3rem);
  border-top: 1px solid var(--oak-faint);
  align-items: baseline;
}
.manifesto li:last-child { border-bottom: 1px solid var(--oak-faint); }
.manifesto li::before {
  content: '0' counter(m);
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--moss);
  font-variant-numeric: tabular-nums;
}
.manifesto p {
  font-family: var(--display);
  font-size: var(--s-1);
  line-height: 1.3;
  max-width: 40ch;
}

/* ---------- disclosure rows (+ expanders) ------------------------------- */

.rows { border-top: 1px solid var(--oak-faint); }
.row { border-bottom: 1px solid var(--oak-faint); }

.row > summary {
  display: grid;
  /* four children: number, title, meta, the + mark */
  grid-template-columns: 2.6rem 1fr auto auto;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  align-items: baseline;
  padding-block: clamp(0.85rem, 1.8vw, 1.2rem);
  cursor: pointer;
  list-style: none;
}
.row > summary::-webkit-details-marker { display: none; }
.r-n {
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.r-t {
  font-family: var(--display);
  font-size: var(--s-1);
  line-height: 1.25;
}
.r-m {
  font-size: var(--s--1);
  color: var(--ink-soft);
  text-align: right;
}
/* the +/- disclosure mark, used by any <summary> on the site */
.r-plus {
  position: relative;
  width: 11px;
  height: 11px;
  flex: none;
  align-self: center;
}
.r-plus::before,
.r-plus::after {
  content: '';
  position: absolute;
  background: var(--oak);
  transition: transform 0.26s var(--ease);
}
.r-plus::before { inset: 5px 0 5px 0; height: 1px; }
.r-plus::after { inset: 0 5px 0 5px; width: 1px; }
[open] > summary .r-plus::after { transform: scaleY(0); }
.r-body {
  padding: 0 0 clamp(1rem, 2.4vw, 1.6rem) 2.6rem;
  max-width: 58ch;
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.65;
}
.row .r-body > * + * { margin-top: 0.8em; }

@media (max-width: 700px) {
  .row > summary { grid-template-columns: 2rem 1fr auto; }
  .row > summary .r-m { display: none; }
  .row .r-m { display: none; }
  .row .r-body { padding-left: 2rem; }
}

/* A listed entry with nothing to disclose: same grid as a row's summary,
   without the expander. Used where the list is the content and there is no
   annotation behind it. */
.row-static {
  display: grid;
  grid-template-columns: 2.6rem 1fr auto;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  align-items: baseline;
  padding-block: clamp(0.8rem, 1.7vw, 1.15rem);
  border-bottom: 1px solid var(--oak-faint);
}

@media (max-width: 700px) {
  .row-static { grid-template-columns: 2rem 1fr; }
  .row-static .r-m { grid-column: 2; text-align: left; padding-top: 0.2rem; }
}

/* ---------- image frames & gallery -------------------------------------- */

.frame {
  position: relative;
  background: var(--paper-warm);
  overflow: hidden;
}
.frame::after {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid var(--oak-faint);
  pointer-events: none;
}
.frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.6s var(--ease);
}
.frame--empty {
  display: grid;
  place-items: center;
  color: var(--oak);
}
.frame--empty svg { width: 44%; max-width: 120px; opacity: 0.75; }

/* A wide photograph sitting in a side column reads as a letterbox with a very
   small subject in it. Cropping the frame upright gives the subject the height
   of the column instead, and object-fit on .frame img does the rest. */
.frame--tall { aspect-ratio: 4 / 5; }

.figure { display: grid; gap: 0.85rem; }
.figure figcaption {
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.5;
  max-width: 44ch;
}
.c-n {
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--walnut);
  display: block;
  margin-bottom: 0.35rem;
}

/* ---------- gallery: a proof sheet, then prints -------------------------- */

/* Both blocks are held to a measure rather than filling the page. Photographs
   at full column width overpower everything around them; kept small they read
   as a set. This is the one number to turn if they want to be bigger. */
:root { --gallery-measure: 860px; }

/* The plate work reads as a photographer's contact sheet: uniform squares,
   tight gutters, numbered. Captions live in the lightbox so the density holds. */
.sheet {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(5px, 0.7vw, 9px);
  max-width: var(--gallery-measure);
}
.sheet .frame { aspect-ratio: 1; }
.sheet figcaption {
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--walnut);
  padding-top: 0.45rem;
}
/* On the sheet only the number shows — the dish is read in the lightbox, where
   this rule does not reach. The alt text still carries it for screen readers. */
.sheet figcaption .cap-t { display: none; }

/* Dropping straight to three columns made the squares larger on a small screen
   than on a large one. A contact sheet should stay a contact sheet. */
@media (max-width: 900px) { .sheet { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 560px) { .sheet { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Everything else is a print: a narrow even mat, gallery framing rather than
   instant film. Widths vary, alignment never does — every edge lands on the
   same twelve-column field, and nothing is rotated. */
.prints {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.35rem);
  align-items: start;
  max-width: var(--gallery-measure);
}
.print {
  background: #fff;
  padding: clamp(4px, 0.45vw, 6px);
  border: 1px solid var(--oak-faint);
}
.print .frame::after { border-color: transparent; }

.w2 { grid-column: span 2; }
.w3 { grid-column: span 3; }
.w4 { grid-column: span 4; }

.w2 .frame { aspect-ratio: 2 / 3; }
.w3 .frame { aspect-ratio: 3 / 4; }
.w4 .frame { aspect-ratio: 1; }

/* These spans were written for a larger gallery and never revisited after the
   measure came down. At a 900px window `span 8` is a 500px photograph, which is
   the opposite of the intent. Keep four-ish across until the screen is genuinely
   small. */
@media (max-width: 900px) {
  .w2 { grid-column: span 3; }
  .w3 { grid-column: span 4; }
  .w4 { grid-column: span 5; }
}
@media (max-width: 560px) {
  .w2 { grid-column: span 4; }
  .w3 { grid-column: span 6; }
  .w4 { grid-column: span 6; }
}

.zoom { cursor: zoom-in; }

/* lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: var(--paper);
  display: grid;
  /* minmax(0, 1fr), not 1fr: a bare `1fr` track carries an automatic minimum of
     its content's intrinsic size, so a 4000px photograph forces the row taller
     than the viewport — and since this is position:fixed, it cannot be scrolled
     back into view either. */
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 1rem;
  padding: clamp(1.5rem, 4vw, 3rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease), visibility 0s linear 0.3s;
}
.lightbox[data-open='true'] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
.lightbox img {
  margin: auto;
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: contain;
}
.lightbox figcaption {
  font-size: var(--s--1);
  color: var(--ink-soft);
  text-align: center;
  max-width: 60ch;
  margin-inline: auto;
}
.lightbox .close {
  position: absolute;
  top: clamp(1rem, 2.4vw, 1.9rem);
  right: var(--gutter);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
}
.lightbox .close svg { width: 16px; height: 16px; }
.lightbox .close line { stroke: var(--ink); stroke-width: 1; }

/* ---------- the map ----------------------------------------------------- */

.map-figure {
  position: relative;
  width: 100%;
}
.map-svg {
  width: 100%;
  height: auto;
  overflow: visible;
}
.map-svg .land {
  fill: none;
  stroke: var(--oak-deep);
  stroke-width: 0.9;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.pin {
  cursor: pointer;
}
.pin .hit { fill: transparent; }
.pin .dot {
  fill: var(--ink);
  transition: r 0.28s var(--ease), fill 0.28s var(--ease);
}
.pin .ring {
  fill: none;
  stroke: var(--moss);
  stroke-width: 1;
  opacity: 0;
  transition: opacity 0.3s var(--ease), r 0.3s var(--ease);
  vector-effect: non-scaling-stroke;
}
.pin:hover .dot,
.pin:focus-visible .dot,
.pin[data-active='true'] .dot { fill: var(--moss); }
.pin:hover .ring,
.pin:focus-visible .ring,
.pin[data-active='true'] .ring { opacity: 1; }
.pin:focus { outline: none; }
.pin:focus-visible .ring { opacity: 1; stroke-width: 1.5; }

html.js .pin { opacity: 0; transition: opacity 0.5s var(--ease); }
html.js .pin.in { opacity: 1; }

.map-note {
  position: absolute;
  z-index: 5;
  background: var(--paper);
  border: 1px solid var(--oak-faint);
  padding: 0.7rem 0.95rem;
  max-width: 22rem;
  font-size: var(--s--1);
  line-height: 1.5;
  color: var(--ink-soft);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.24s var(--ease), transform 0.24s var(--ease);
}
.map-note[data-open='true'] { opacity: 1; transform: none; }
.map-note strong {
  display: block;
  font-family: var(--display);
  font-size: var(--s-1);
  font-weight: 300;
  color: var(--ink);
  line-height: 1.2;
}
.map-note .yr {
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--moss);
  font-variant-numeric: tabular-nums;
}

/* On a phone the map is a quiet header and the list does the work, so the
   annotation sits under the drawing instead of covering it. */
@media (max-width: 640px) {
  .map-note {
    position: static;
    max-width: none;
    margin-top: 1rem;
    transform: none;
  }
  .map-note:not([data-open='true']) { display: none; }
}

/* ---------- trips: routes, stops, magnifier ------------------------------ */

/* Roads, not flight paths. Amber so a journey never reads as a location. */
.route {
  fill: none;
  stroke: var(--amber);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: 1;
  transition: stroke-width 0.3s var(--ease), opacity 0.3s var(--ease);
}
.stop {
  fill: var(--ink);
  transition: r 0.3s var(--ease);
}

/* the clickable target: invisible, and wide enough for a finger */
.route-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 12;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  cursor: pointer;
}
.route-group:hover .route,
.route-group:focus-visible .route { stroke-width: 3; opacity: 1; }
.routes [data-active='true'],
.route:hover { stroke-width: 3; opacity: 1; }

/* dim the rest while one trip is being read */
.map-svg[data-focus] .route:not([data-active='true']) { opacity: 0.18; }
.map-svg[data-focus] .stop:not([data-active='true']) { opacity: 0.2; }

/* Scoped to the world map: the magnifier injects its own route, which must not
   inherit an entrance animation it will never be given the class for. */
html.js .map-svg .route { opacity: 0; transition: opacity 0.6s var(--ease); }
html.js .map-svg .route.in { opacity: 1; }

/* the magnifier: a circular window onto real detail, because at world scale
   the Ligurian coast is six pixels long */
.magnifier {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
  z-index: 4;
}
.magnifier[data-open='true'] { opacity: 1; pointer-events: auto; }

/* While the lens is up nothing underneath it should respond to the pointer:
   an area note opening on hover lands on top of the thing being read. */
.map-figure[data-magnified] .pins,
.map-figure[data-magnified] .routes { pointer-events: none; }
.map-figure[data-magnified] .map-note { display: none; }

.mag-lens {
  width: min(72vw, 440px);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--oak);
  display: grid;
  place-items: center;
}
.mag-lens svg { width: 100%; height: 100%; }
.mag-lens .land {
  fill: none;
  stroke: var(--oak-deep);
  stroke-width: 1;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.mag-lens .route { opacity: 1; stroke-width: 2.4; }
.mag-lens .stop { fill: var(--ink); }
.mag-lens .leader {
  stroke: var(--ink-soft);
  stroke-width: 0.6;
  opacity: 0.55;
}
.mag-lens .stop-label {
  font-family: var(--text);
  font-size: 10px;
  font-weight: 450;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3px;      /* a halo, so a name crossing the coastline still reads */
  stroke-linejoin: round;
}
.mag-name {
  margin-top: 0.9rem;
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

/* ---------- the trip list ----------------------------------------------- */

.trips { border-top: 1px solid var(--oak-faint); }
.trip { border-bottom: 1px solid var(--oak-faint); }

.trip-head {
  width: 100%;
  display: grid;
  grid-template-columns: 2.6rem 1fr auto 2.5rem;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  align-items: baseline;
  padding-block: clamp(0.85rem, 1.8vw, 1.2rem);
  /* it is a button, and the browser's own 6px inline padding pushed this row's
     columns out of step with the place rows below */
  padding-inline: 0;
  text-align: left;
}
.trip-head .t-i { font-size: var(--label); letter-spacing: 0.1em; color: var(--ink-soft); }
.trip-head .t-n {
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-1);
  line-height: 1.25;
  letter-spacing: -0.004em;
}
.trip-head .t-w { font-size: var(--s--1); color: var(--ink-soft); }
.trip-head .t-c {
  font-size: var(--label);
  color: var(--amber);
  text-align: right;
}
.trip[data-open='true'] .t-n,
.trip-head:hover .t-n { color: var(--ink); }

.trip-stops {
  display: none;
  padding: 0 0 clamp(1rem, 2.4vw, 1.5rem) 2.6rem;
  columns: 2;
  column-gap: 2.5rem;
  max-width: 46rem;
}
.trip[data-open='true'] .trip-stops { display: block; }
.trip-stops li {
  font-size: var(--s--1);
  color: var(--ink-soft);
  padding-block: 0.22rem;
  break-inside: avoid;
}
.trip-stops li::before {
  content: '';
  display: inline-block;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--ink);
  margin-right: 0.6rem;
  vertical-align: 0.16em;
}

@media (max-width: 700px) {
  .trip-head { grid-template-columns: 2rem 1fr auto; }
  .trip-head .t-w { display: none; }
  .trip-stops { columns: 1; padding-left: 2rem; }
}

/* Cities are grouped under the country they sit in, so the country is stated
   once as a heading rather than repeated on all eleven French entries. */
.places { border-top: 1px solid var(--oak-faint); }
.place-group { border-bottom: 1px solid var(--oak-faint); }
.place-group:last-child { border-bottom: 0; }
.p-country {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-family: var(--text);
  font-size: var(--label);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--walnut);
  margin: 0;
  padding-block: clamp(0.9rem, 2vw, 1.3rem) 0.2rem;
}
.p-country .p-count { color: var(--oak-deep); }

.place {
  display: grid;
  /* the trailing 2.5rem is empty: it reserves the same width the trip rows give
     their count, so a city's detail stops where a trip's country stops */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) 2.5rem;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  align-items: baseline;
  padding-block: clamp(0.55rem, 1.3vw, 0.85rem);
  transition: background 0.3s var(--ease);
  cursor: default;
}
.place[data-active='true'] { background: var(--paper-warm); }
.place .p-n { font-family: var(--display); font-size: var(--s-1); line-height: 1.2; }
.place .p-d {
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.55;
  text-align: right;   /* sits under the country count, not adrift in the middle */
}

@media (max-width: 760px) {
  .place { grid-template-columns: 1fr; gap: 0.2rem; }
  .place .p-d { text-align: left; }
}

.tally {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}
.tally div { display: grid; gap: 0.3rem; }
.tally .t-n {
  font-family: var(--display);
  font-size: var(--s-3);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* ---------- CV / timeline ----------------------------------------------- */

.cv { border-top: 1px solid var(--oak-faint); }
.cv-item {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: clamp(0.75rem, 2vw, 2rem);
  padding-block: clamp(1rem, 2.2vw, 1.5rem);
  border-bottom: 1px solid var(--oak-faint);
}
.cv-item .y {
  font-size: var(--label);
  letter-spacing: 0.08em;
  color: var(--moss);
  font-variant-numeric: tabular-nums;
  padding-top: 0.45rem;
}
/* the environment number, sitting above its title like an index entry */
.env-n {
  font-size: var(--label);
  letter-spacing: 0.14em;
  color: var(--moss);
  margin-bottom: 0.35rem;
}
.cv-item h3 { font-family: var(--display); font-size: var(--s-1); font-weight: 300; line-height: 1.2; }
.cv-item .meta { font-size: var(--s--1); color: var(--ink-soft); margin-top: 0.35rem; }
.cv-item .note { font-size: var(--s--1); color: var(--ink-soft); margin-top: 0.7rem; max-width: 52ch; }

@media (max-width: 700px) {
  .cv-item { grid-template-columns: 1fr; gap: 0.4rem; }
  .cv-item .y { padding-top: 0; }
}

/* ---------- CV sub-disclosure ------------------------------------------- */
/* A second level inside a CV entry, for the detail only some readers want:
   what was actually studied, and what the qualification actually is. */

.cv-item details.sub { margin-top: 0.9rem; }

.cv-item details.sub > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  padding-block: 0.35rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--text);
  font-size: var(--label);
  font-weight: 450;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color 0.3s var(--ease);
}
.cv-item details.sub > summary::-webkit-details-marker { display: none; }
.cv-item details.sub > summary:hover,
.cv-item details.sub > summary:focus-visible { color: var(--ink); }

.sub-body {
  padding-top: 1.1rem;
  max-width: 62ch;
  display: grid;
  gap: 1.35rem;
}
.sub-group { display: grid; gap: 0.55rem; }

/* fields of study read as one quiet run rather than a bulleted column */
.run {
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.75;
}
/* direct children only: each field is wrapped, and inside it sit the two
   language spans, which must not each grow a separator of their own */
.run > span::after { content: ' · '; color: var(--oak); }
.run > span:last-child::after { content: ''; }

.marks { display: grid; gap: 0.6rem; }
.marks li {
  position: relative;
  padding-left: 1.1rem;
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.55;
}
.marks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 6px;
  height: 1px;
  background: var(--oak);
}
.marks strong { font-weight: 450; color: var(--ink); }

/* the rosette sits with the name, not after the line */
.rosette {
  display: inline-block;
  width: 0.95em;
  height: 0.95em;
  vertical-align: -0.13em;
  margin-left: 0.45em;
  color: var(--ink);
}

/* points belonging to a single qualification */
.marks-sub {
  display: grid;
  gap: 0.3rem;
  margin-top: 0.45rem;
}
.marks-sub li {
  position: relative;
  padding-left: 0.95rem;
  font-size: 0.92em;
  line-height: 1.5;
  color: var(--ink-soft);
}
.marks-sub li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--oak);
}
/* ---------- menus (course lists) ---------------------------------------- */

.menu-card {
  border: 1px solid var(--oak-faint);
  padding: clamp(1.5rem, 3.5vw, 3rem);
}
.courses { counter-reset: c; margin-top: 1.5rem; }
.courses li {
  counter-increment: c;
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: 1rem;
  padding-block: 0.85rem;
  border-top: 1px solid var(--oak-faint);
  align-items: baseline;
}
.courses li::before {
  content: counter(c, decimal-leading-zero);
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--walnut);
  font-variant-numeric: tabular-nums;
}
.courses p {
  font-family: var(--display);
  font-size: var(--s-1);
  line-height: 1.3;
  max-width: 46ch;
}

/* ---------- thesis page: process, preps, menu ---------------------------- */

/* the page is the thesis; the theme is what this one is about, so it sits
   under the title rather than replacing it */
.theme-label {
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--moss);
  margin-top: 0.35rem;
}
.theme-name {
  margin-top: 0.1rem;
  max-width: 20ch;
  text-wrap: balance;
}

/* the standing conditions of the menu, under the title */
.thesis-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.4rem;
  align-items: baseline;
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-block: 0.9rem;
  border-top: 1px solid var(--oak-faint);
  border-bottom: 1px solid var(--oak-faint);
}
.thesis-meta .sep { color: var(--oak); }
.thesis-meta strong { font-weight: 450; color: var(--moss); }

/* six passes: a lead instruction, then why */
.process { counter-reset: pass; border-top: 1px solid var(--oak-faint); }
.process li {
  counter-increment: pass;
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  padding-block: clamp(1rem, 2.2vw, 1.5rem);
  border-bottom: 1px solid var(--oak-faint);
}
.process li::before {
  content: counter(pass, decimal-leading-zero);
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--moss);
  font-variant-numeric: tabular-nums;
  padding-top: 0.3rem;
}
.process .lead {
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-1);
  line-height: 1.3;
  letter-spacing: -0.004em;
  max-width: 40ch;
}
.process p {
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: 58ch;
  margin-top: 0.5rem;
}

/* one prep, one job */
.prep { padding-top: clamp(1.75rem, 4vw, 3rem); }
.prep + .prep { border-top: 1px solid var(--oak-faint); margin-top: clamp(1.5rem, 3vw, 2.5rem); }
.prep-head { display: grid; gap: 0.5rem; margin-bottom: 1rem; }
.prep-head h3 {
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-2);
  line-height: 1.15;
  letter-spacing: -0.006em;
}
.prep-head .attrs {
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--walnut);
}
.prep > p {
  font-family: var(--text);
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.65;
  max-width: 62ch;
  margin-bottom: 1.5rem;
}

/* what it goes with: a row per category, no header — the structure says it */
.pairs { width: 100%; border-collapse: collapse; }
.pairs tr { border-top: 1px solid var(--oak-faint); }
.pairs tr:last-child { border-bottom: 1px solid var(--oak-faint); }
.pairs th {
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
  width: 9rem;
  font-family: var(--text);
  font-size: var(--label);
  font-weight: 450;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0.7rem 1.5rem 0.7rem 0;
}
.pairs td {
  font-size: var(--s--1);
  color: var(--ink);
  line-height: 1.55;
  padding: 0.7rem 0;
}

@media (max-width: 640px) {
  .pairs th, .pairs td { display: block; width: auto; white-space: normal; }
  .pairs th { padding-bottom: 0.15rem; }
  .pairs td { padding-top: 0; }
}

/* the menu itself */
.movement {
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--moss);
  padding-block: 0.6rem;
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  border-bottom: 1px solid var(--oak-faint);
}
.course {
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  padding-block: clamp(1rem, 2.2vw, 1.5rem);
  border-bottom: 1px solid var(--oak-faint);
}
.course .c-i {
  font-family: var(--text);
  font-size: var(--label);
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  padding-top: 0.3rem;
}
.course h4 {
  font-family: var(--display);
  font-weight: 300;
  font-size: var(--s-1);
  line-height: 1.28;
  letter-spacing: -0.004em;
  max-width: 34ch;
}
.course p {
  font-size: var(--s--1);
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: 58ch;
  margin-top: 0.55rem;
}
.tag {
  display: inline-block;
  font-family: var(--text);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--walnut);
  border: 1px solid var(--oak-faint);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  margin-top: 0.6rem;
  white-space: nowrap;
}

/* ---------- recipe ------------------------------------------------------ */

.recipe { border-top: 1px solid var(--oak-faint); padding-top: clamp(1.5rem, 3vw, 2.5rem); }
.recipe-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: start;
}
@media (max-width: 800px) { .recipe-grid { grid-template-columns: 1fr; } }

.ingredients li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.5rem;
  border-bottom: 1px solid var(--oak-faint);
  font-size: var(--s--1);
}
.ingredients li span:last-child { color: var(--ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }

.method { counter-reset: st; }
.method li {
  counter-increment: st;
  display: grid;
  grid-template-columns: 2.2rem 1fr;
  gap: 1rem;
  padding-block: 0.75rem;
  align-items: baseline;
}
.method li::before {
  content: counter(st, decimal-leading-zero);
  font-size: var(--label);
  color: var(--walnut);
  font-variant-numeric: tabular-nums;
}
.method p { max-width: 56ch; }

/* ---------- form -------------------------------------------------------- */

.field { display: grid; gap: 0.5rem; margin-bottom: 1.5rem; }
.field input,
.field textarea {
  font: inherit;
  font-size: var(--s--1);
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--oak);
  padding: 0.6rem 0;
  border-radius: 0;
}
.field textarea { resize: vertical; min-height: 7rem; }
.field input:focus, .field textarea:focus {
  outline: none;
  border-bottom-color: var(--ink);
}
.btn {
  font-size: var(--label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  border: 1px solid var(--ink);
  padding: 0.9rem 1.8rem;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.btn:hover, .btn:focus-visible { background: var(--ink); color: var(--paper); }
.hp { position: absolute; left: -9999px; }

/* ---------- footer ------------------------------------------------------ */

.foot {
  border-top: 1px solid var(--oak-faint);
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  font-size: var(--s--1);
  color: var(--ink-soft);
}
.foot a { text-decoration: none; border-bottom: 1px solid var(--oak); padding-bottom: 1px; }
.foot a:hover { border-bottom-color: var(--ink); color: var(--ink); }

.lang-toggle {
  display: inline-flex;
  gap: 0.5rem;
  align-items: baseline;
  font-size: var(--label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.lang-toggle button { color: var(--ink-soft); transition: color 0.25s var(--ease); }
.lang-toggle button[aria-pressed='true'] { color: var(--ink); }
.lang-toggle .sep { color: var(--oak); }

/* ---------- language switch --------------------------------------------- */
/* Default is English, done in CSS so it is correct with JavaScript disabled. */

body [lang='cs'] { display: none; }
html[data-lang='cs'] body [lang='cs'] { display: revert; }
html[data-lang='cs'] body [lang='en'] { display: none; }

/* ---------- motion ------------------------------------------------------ */
/* .js is set by an inline script, so no-JS never hides content. */

html.js .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
html.js .reveal.in { opacity: 1; transform: none; }

html.js .draw {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--ease);
}
html.js .draw.in { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  html.js .reveal,
  html.js .draw,
  html.js .pin {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ---------- print ------------------------------------------------------- */

@media print {
  :root { --paper: #fff; --paper-warm: #fff; }
  .topbar, .panel, .menu-btn, .pager, .pager-wrap, .foot, .lightbox,
  .map-figure, .skip, .btn, form { display: none !important; }
  body { font-size: 11pt; line-height: 1.5; color: #000; }
  .section { padding-block: 0.5rem; }
  .recipe { page-break-inside: avoid; break-inside: avoid; border-top: 1px solid #999; }
  .row > summary { cursor: default; }
  .row .r-plus { display: none; }
  .row[open] .r-body, .r-body { display: block !important; }
  details:not([open]) .r-body { display: block !important; }
  a { text-decoration: none; }
  .frame { border: 1px solid #ccc; }
}
