:root {
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: #e8f0e2;
  background: #03120a;
  -webkit-text-size-adjust: 100%;
  /* Light only, by choice. Declaring it stops the browser's own dark-mode pass from
     repainting the page and the form controls. */
  color-scheme: dark;
  /* Height of the sticky chrome above the material. Anchor jumps offset by it, so a tapped
     exercise does not land underneath the bar. */
  --bar: 56px;

  /* Glass surfaces. Frosted panes over the page gradient: a translucent white fill, a lit top
     edge, and a soft drop shadow to lift the pane off the background. Only panes that sit
     directly on the gradient carry `--blur`; anything nested inside one takes a plain
     translucent fill, because stacking backdrop filters is what makes this style expensive. */
  /* Panes are a smoked green, lighter than the artwork behind them - they read as frosted glass
     lying on the picture rather than as holes cut out of it. Alpha stays around half, so a blob
     passing behind a pane still shows. */
  --glass: rgba(112, 136, 114, .44);
  --glass-strong: rgba(138, 162, 138, .54);
  --glass-line: rgba(255, 255, 255, .28);
  --glass-edge: rgba(255, 255, 255, .16);
  --shadow: 0 12px 44px rgba(0, 0, 0, .55);
  --shadow-lift: 0 18px 54px rgba(0, 0, 0, .68);
  /* Lime is the one accent: translations, links, active edges. */
  --lime: #a3e635;
  /* The accent has to clear a pane that is itself half-lit, so it sits well above the
     mid-green the panes land on. */
  --lime-bright: #e2ffa3;
  --muted: rgba(240, 247, 236, .76);
  /* Low saturation on purpose: the artwork behind a pane is lime, and boosting it is what pushed
     the card towards the same green as its own text. */
  --blur: blur(14px) saturate(105%);
  --radius: 18px;
  --radius-sm: 12px;
}
* { box-sizing: border-box; }
body { margin: 0; min-width: 320px; }

/* The glass has to have something to refract, so the page itself is a soft gradient. It is a
   fixed pseudo-element rather than a background on `body`: `background-attachment: fixed` is
   the buggiest property on iOS Safari, and this pins just as well and prints as nothing. */
body::before {
  content: '';
  position: fixed;
  z-index: -1;
  inset: 0;
  background: url('background.svg') center center / cover no-repeat #03120a;
}
button, select, input { font: inherit; }
/* Phones and tablets: no hover state to fall back on, so the press itself has to read. */
@media (hover: none) {
  a, button { -webkit-tap-highlight-color: rgba(163, 230, 53, .22); }
}

.shell {
  width: min(1040px, 100%);
  margin: 0 auto;
  padding:
    0 max(16px, env(safe-area-inset-right))
    calc(56px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}

/* Sticky navigation bar: back one level, home to the section list, and the name of where you are.
   Two separate controls on purpose - back is a step up the hierarchy and home is a jump, and on a
   phone deep inside section 4 those are very different distances. */
.navbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--bar);
  padding:
    max(6px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right))
    6px max(12px, env(safe-area-inset-left));
  border-bottom: 1px solid var(--glass-line);
  background: var(--glass);
  box-shadow: 0 2px 30px rgba(0, 0, 0, .45);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
}
.navbtn {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  background: var(--glass-strong);
  color: var(--lime-bright);
  text-decoration: none;
  transition: transform .12s ease, border-color .12s ease;
}
/* At the root there is nowhere to go back to, so that button is not there. Home stays, marked as
   the page you are on. */
.navbtn[hidden] { display: none; }

.navbtn[aria-current="page"] { border-color: var(--lime); background: rgba(163, 230, 53, .16); }
.navbtn:hover { border-color: var(--lime); }
.navbtn:active { transform: scale(.94); }
.navbtn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* Sits directly after the buttons, against the left. Centring it in the leftover space made the
   title drift sideways as the button count changed between views; an edge does not move. */
.navtitle {
  flex: 1;
  /* On top of the bar's own gap: the buttons belong together, the title does not belong to them. */
  margin-left: 8px;
  min-width: 0;
  overflow: hidden;
  color: #f2f7ee;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .4px;
  text-align: left;
  text-overflow: ellipsis;
  /* Duolingo writes its unit names in lower case; this is where they get their capitals. */
  text-transform: capitalize;
  white-space: nowrap;
}

.top { display: flex; align-items: end; justify-content: space-between; gap: 18px; margin-bottom: 18px; }
.top > div { min-width: 0; }
/* A unit page is the material and nothing else: the bar names the lesson and the trail says where
   it sits, so the page title and the entry count would only repeat them. */
body[data-view="unit"] .top { display: none; }
/* The page title, its label and the count sit straight on the artwork, not on a pane, so they are
   the one place the type goes light. Everything inside a pane stays near-black. */
/* The nav bar already names the site on screen, so this is print-only: on paper there is no bar
   above the title to say what the sheet is. */
.eyebrow { display: none; color: var(--lime); font-size: 12px; font-weight: 900; letter-spacing: 1px; text-transform: uppercase; text-shadow: 0 1px 12px rgba(0, 0, 0, .6); }
h1 { margin: 4px 0 0; color: #f2f7ee; font-size: clamp(26px, 5vw, 44px); line-height: 1.05; text-shadow: 0 2px 18px rgba(0, 0, 0, .55); }
.stats { color: var(--muted); font-weight: 800; white-space: nowrap; text-shadow: 0 1px 12px rgba(0, 0, 0, .55); }


.material { display: grid; gap: 22px; margin-top: 18px; }
.group {
  /* A unit can hold a thousand entries. Off-screen exercises are skipped entirely during layout
     and paint, which is what keeps scrolling smooth on a phone; the placeholder size stops the
     scrollbar from jumping as they are reached. Print switches this back off. */
  content-visibility: auto;
  /* Longhands, not `contain-intrinsic-size`: the shorthand applies the placeholder to BOTH axes,
     and a 600px intrinsic width escapes as the page's min-content, stretching every card past a
     phone screen. Only the height needs a guess. */
  contain-intrinsic-width: none;
  contain-intrinsic-height: auto 600px;
  padding: 22px 24px;
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  background: var(--glass);
  box-shadow: var(--shadow);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  /* The heading band is pulled out to the card edges, so it has to be clipped to the radius. */
  overflow: hidden;
}
/* One dark tint per exercise type, so a long unit page is scannable by colour. These replace the
   pane's own background rather than sitting on top of it, so they carry the pane's opacity: any
   lighter and the lime artwork behind a card shows through the text. */
.type-name { background: hsl(35 14% 42% / .44); }
.type-match { background: hsl(105 14% 42% / .44); }
.type-select { background: hsl(205 14% 42% / .44); }
.type-assist { background: hsl(285 14% 42% / .44); }
.type-definition { background: hsl(0 14% 42% / .44); }
.type-translate { background: hsl(225 14% 42% / .44); }
.type-completeReverseTranslation { background: hsl(160 14% 42% / .44); }
.type-partialReverseTranslate { background: hsl(50 14% 42% / .44); }
.type-tapComplete { background: hsl(260 14% 42% / .44); }
.type-gapFill { background: hsl(20 14% 42% / .44); }
.type-dialogue { background: hsl(185 14% 42% / .44); }
.type-readComprehension { background: hsl(75 14% 42% / .44); }
.type-story { background: hsl(330 14% 42% / .44); }

/* The heading is a band across the top of the card, pulled out to the card's own edges. A tinted
   band separates it from the entries without adding a rule, which on paper only read as clutter.
   The tint is neutral and translucent, so it darkens whichever type colour sits behind it. */
.group h2 {
  display: flex;
  /* Centred, not baseline: the icon is a disc with no baseline of its own, so baseline alignment
     left it sitting high against the label. */
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: -22px -24px 18px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--glass-line);
  background: rgba(255, 255, 255, .1);
  font-size: 19px;
}
.group-meta { color: var(--muted); font-size: 12px; font-weight: 800; letter-spacing: .6px; text-align: right; text-transform: uppercase; }

/* Exercise-type icons: a filled disc in the type's colour with the mark knocked out of it. The
   disc is the only thing that takes `currentColor`; the mark is the page showing through. */
.type-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  align-self: center;
  /* The disc is a background the browser would otherwise drop when printing. */
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
.icon-disc { fill: currentColor; stroke: none; }
.icon-mark {
  fill: none;
  /* The mark is the pane showing through the disc, so it follows the pane, not the page. */
  stroke: #eaf3e6;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.group h2 .type-icon { width: 34px; height: 34px; }

/* Each disc takes the saturated version of its type's tint, so icon and box read as one colour. */
.type-name .type-icon { color: hsl(35 80% 62%); }
.type-match .type-icon { color: hsl(105 45% 53%); }
.type-select .type-icon { color: hsl(205 70% 60%); }
.type-assist .type-icon { color: hsl(285 40% 66%); }
.type-definition .type-icon { color: hsl(0 60% 66%); }
.type-translate .type-icon { color: hsl(225 55% 68%); }
.type-completeReverseTranslation .type-icon { color: hsl(160 55% 52%); }
.type-partialReverseTranslate .type-icon { color: hsl(50 75% 55%); }
.type-tapComplete .type-icon { color: hsl(260 50% 68%); }
.type-gapFill .type-icon { color: hsl(20 70% 65%); }
.type-dialogue .type-icon { color: hsl(185 60% 53%); }
.type-readComprehension .type-icon { color: hsl(75 45% 53%); }
.type-story .type-icon { color: hsl(330 55% 66%); }

ol { margin: 0; padding: 0; list-style: none; }

/* Grid, not CSS columns: multi-column fills the left column top to bottom first, so entry 5 of 8
   jumped to the right. Reading order should go left, right, next row. */
.words {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 34px;
}
.words li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  padding: 7px 0;
  border-bottom: 1px solid var(--glass-edge);
  break-inside: avoid;
}
.words .es { font-size: 17px; font-weight: 800; }
.words .en { color: var(--lime-bright); font-size: 16px; font-weight: 700; text-align: right; }

.sentences li { padding: 11px 0; border-bottom: 1px solid var(--glass-edge); break-inside: avoid; }
.sentences p { margin: 0; overflow-wrap: anywhere; }
.sentences .es { font-size: 18px; font-weight: 800; line-height: 1.3; }
.sentences .en { margin-top: 3px; color: var(--lime-bright); font-size: 16px; font-weight: 600; line-height: 1.3; }

/* Dialogue lines arrive newline-separated, one speaker turn per line. */
.es.lines { white-space: pre-line; }

/* Reading passages: Spanish passage, then Duolingo's question and its answer. */
.readings li { padding: 14px 0; border-bottom: 1px solid var(--glass-edge); break-inside: avoid; }
.readings p { margin: 0; overflow-wrap: anywhere; }
.passage { font-size: 17px; font-weight: 700; line-height: 1.4; }
.question { margin-top: 8px; color: var(--muted); font-size: 15px; font-weight: 800; }
.answer { margin-top: 2px; color: var(--lime-bright); font-size: 16px; font-weight: 700; }

/* Feminine Spanish nouns. */
.es.feminine { color: #ff8da2; }

/* The last entry's own padding sat on top of the card's, so the gap under a list came out bigger
   than the gap beside it. */
li:last-child { padding-bottom: 0; border-bottom: 0; }
.empty { padding: 28px; color: var(--muted); font-weight: 800; text-align: center; text-shadow: 0 1px 12px rgba(0, 0, 0, .55); }

/* Word pairs are short, so two columns still fit a tablet in portrait; below that one column, with
   the English pushed onto its own line rather than squeezed against the right edge. */
@media (max-width: 719px) {
  .words { grid-template-columns: 1fr; }
}

/* Tablet and phone. The material is read here, so the type gets bigger, not smaller: only the
   chrome around it shrinks. */
@media (max-width: 719px) {
  .shell { padding-top: 0; }

  .top { align-items: start; flex-direction: column; gap: 2px; margin-bottom: 14px; }
  .stats { font-size: 13px; }
  h1 { font-size: clamp(22px, 6vw, 30px); }

  .group { padding: 16px; border-radius: var(--radius-sm); }
  .group h2 { margin: -16px -16px 14px; padding: 12px 16px; font-size: 17px; }
  .group-meta { font-size: 11px; }

  .words li { padding: 9px 0; }
  .words .es, .sentences .es, .story-lines .es { font-size: 18px; }
  .words .en, .sentences .en { font-size: 16px; }
  .sentences li { padding: 12px 0; }
  .passage { font-size: 18px; }

  /* Printing is a desktop job; on a phone these only lead to a several-thousand-entry page that
     takes seconds to build and cannot be printed anyway. */
  .print-row, .print-link { display: none; }
}


/* Breadcrumb: Sections / Section 1 / Unit 1 */
/* Fixed under the bar: in a unit the trail is the only thing left saying where you are, so it
   cannot scroll away with the first exercise. The negative margins let its background run to the
   window edges while its text stays in the page column. */
.trail {
  position: sticky;
  top: calc(var(--bar) + env(safe-area-inset-top));
  z-index: 25;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-inline: calc(-1 * max(16px, env(safe-area-inset-left))) calc(-1 * max(16px, env(safe-area-inset-right)));
  padding: 8px max(16px, env(safe-area-inset-right)) 8px max(16px, env(safe-area-inset-left));
  border-bottom: 1px solid var(--glass-line);
  background: var(--glass);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
}
/* At the root the trail would be one crumb and no steps, which is nothing worth a bar. */
body[data-view="sections"] .trail { display: none; }

.breadcrumb { display: flex; flex: 1; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }

/* Previous / next lesson. Deliberately quiet: the trail beside them is what you read, these are
   reached for once a lesson. Small enough not to compete, with the tap area pushed back out to
   full size by the pseudo-element rather than by the box you can see. */
.steps { display: flex; flex: 0 0 auto; gap: 2px; }
.steps a, .steps span {
  position: relative;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin: -6px 0;
  border-radius: 999px;
  color: var(--muted);
  text-decoration: none;
}
.steps a::after { content: ''; position: absolute; inset: -7px -6px; }
.steps a:hover { background: rgba(163, 230, 53, .14); color: var(--lime-bright); }
.steps a:active { transform: scale(.92); }
.steps .is-off { opacity: .25; pointer-events: none; }
.steps svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.breadcrumb a, .breadcrumb span {
  color: var(--muted);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .4px;
  text-transform: uppercase;
}
.breadcrumb a { color: var(--lime); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb a + a::before, .breadcrumb a + span::before { content: '/'; margin-right: 8px; color: rgba(232, 240, 226, .3); }

/* Section and unit pickers: big tap targets, no dropdowns. */
.picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.picker.units { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.picker a {
  display: grid;
  gap: 6px;
  min-height: 96px;
  align-content: center;
  padding: 18px 20px;
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  background: var(--glass);
  box-shadow: var(--shadow);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  color: #f2f7ee;
  text-decoration: none;
  transition: transform .14s ease, box-shadow .14s ease, background .14s ease;
}
.picker a:hover { border-color: var(--lime); background: var(--glass-strong); box-shadow: var(--shadow-lift); transform: translateY(-2px); }
.picker a:active { transform: scale(.985); }
.picker .pick-title { font-size: 22px; font-weight: 800; line-height: 1.1; }
/* On the section list the name is the whole button, so it carries the accent itself; in the unit
   list that job belongs to the index line above the name. */
.picker:not(.units) .pick-title { color: var(--lime); }
.picker .pick-meta { color: var(--muted); font-size: 13px; font-weight: 700; }
.picker a.empty-unit { opacity: .5; }

/* Picture exercises (select, name): tiles, not wide rows. A row put the picture and the Spanish
   word on the left and pushed the English to the far right, leaving a long empty gap between. */
.words.illustrated {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 14px;
}
.words.illustrated li {
  /* Square tiles, content centred on both axes. Flex column beats grid here because the picture
     can then shrink to whatever space the words leave. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  aspect-ratio: 1;
  padding: 14px;
  border: 1px solid var(--glass-line);
  border-radius: var(--radius-sm);
  /* Nested inside the card's own glass, so a fill rather than another blur pass. Duolingo's
     illustrations are line art drawn for a white page, so the tile stays light even here. */
  background: rgba(255, 255, 255, .88);
  box-shadow: 0 2px 10px rgba(31, 38, 135, .06);
  text-align: center;
  overflow: hidden;
}
.words.illustrated li:hover { background: #fff; box-shadow: var(--shadow); }
/* The picture takes a fixed share of the square tile. It needs a definite height, otherwise
   max-height percentages have nothing to resolve against and the SVG renders at its own size. */
.words.illustrated .thumb {
  flex: 0 0 auto;
  width: 58%;
  height: auto;
  aspect-ratio: 1;
}
.words.illustrated .thumb img { width: 100%; height: 100%; object-fit: contain; }
/* The tile is a light plate inside a dark pane, so its own type flips back to dark. */
.words.illustrated .es { color: #1d2b22; }
.words.illustrated .en { color: #3d7a00; }
.words.illustrated .es.feminine { color: #c8203f; }
.words.illustrated .es,
.words.illustrated .en { width: 100%; text-align: center; }
.words.illustrated .es { font-size: 17px; line-height: 1.2; }
.words.illustrated .en { font-size: 15px; line-height: 1.2; }
.thumb {
  display: grid;
  place-items: center;
  flex: 0 0 112px;
  width: 112px;
  height: 112px;
}
/* Duolingo's illustrations are line art drawn for a white page; a plain pane behind them keeps
   them readable wherever the gradient happens to be darkest. */
.words:not(.illustrated) .thumb:has(img) { border-radius: var(--radius-sm); background: rgba(255, 255, 255, .72); }
.thumb img { width: 112px; height: 112px; object-fit: contain; }
@media (max-width: 460px) {
  .thumb { flex-basis: 88px; width: 88px; height: 88px; }
  .thumb img { width: 88px; height: 88px; }
}

/* Unit buttons carry Duolingo's own unit name. */
.picker.named a { align-content: start; min-height: 104px; }
.pick-index { color: var(--lime); font-size: 12px; font-weight: 900; letter-spacing: .8px; text-transform: uppercase; }
.picker.named .pick-title { font-size: 17px; line-height: 1.25; text-transform: capitalize; }

/* Screen chrome for the exercise heading and the print buttons. */
.group h2 { gap: 10px; }
.group-name { flex: 1; }
.print-row { margin-bottom: 16px; }
.print-row button {
  min-height: 44px;
  padding: 0 20px;
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  background: var(--glass-strong);
  box-shadow: var(--shadow);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  color: #e8f0e2;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
}
.print-row button:hover { border-color: var(--lime); box-shadow: var(--shadow-lift); color: var(--lime-bright); }
.print-link { margin: 18px 0 0; }
.print-link a { color: var(--lime); font-weight: 800; text-decoration: none; text-shadow: 0 1px 12px rgba(0, 0, 0, .55); }
.print-link a:hover { text-decoration: underline; }
/* The unit is marked up as a table so its header repeats on every printed page. On screen the
   table rows and cells are laid back out as plain blocks; only print puts them back. */
.unit-print,
.unit-print > thead,
.unit-print > tbody,
.unit-print tr,
.unit-print th,
.unit-print td { display: block; padding: 0; text-align: left; font-weight: inherit; }
.unit-print { width: 100%; border-collapse: collapse; }
.unit-print > tbody.material { display: grid; gap: 22px; }

/* The running head is print-only: on screen the breadcrumb and page title already say it. The
   selector has to beat the `thead` rule above, which is why it names the element too. */
.unit-print > thead.unit-head { display: none; }
.unit-head-row { display: flex; align-items: center; gap: 12px; }
.unit-titles { display: grid; gap: 1px; }
.unit-where { color: #999; font-size: 12px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; }
.unit-badge {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  background: #1b2a4a;
  color: #fff;
  font-size: 19px;
  font-weight: 900;
}
.unit-name { font-size: 22px; font-weight: 800; text-transform: capitalize; }
.unit-print + .unit-print { margin-top: 36px; }

/* ---------------------------------------------------------------------------
   Print: a two-column coursebook page, the way a repetytorium is set.
   --------------------------------------------------------------------------- */
@media print {
  /* No paper size here: whatever is picked in the print dialog is used, and the content fills it.
     The page number goes in a margin box: it cannot live in the running head, because nothing in
     the page's own content can read `counter(page)` - only the page margins can. Browsers that do
     not implement margin boxes simply ignore this, and the print dialog's own "Headers and
     footers" option prints a page number instead. */
  @page {
    margin: 10mm 10mm 14mm;
    @bottom-center {
      content: counter(page);
      font-family: Inter, ui-sans-serif, system-ui, "Segoe UI", sans-serif;
      font-size: 9pt;
      font-weight: 800;
      color: #7a8aa0;
    }
  }

  /* Screen colours are inverted for a dark pane; on paper everything goes back to ink. */
  html, body { background: #fff; color: #111; font-size: 11pt; }
  .group, .words .es, .sentences .es, .passage, .story-lines .es, .unit-head-row,
  .words.illustrated .es { color: #111; }
  .icon-mark { stroke: #fff; }
  .shell { width: 100%; max-width: none; margin: 0; padding: 0; }

  /* Navigation, search and buttons are screen-only. */
  .navbar, .trail, .print-row, .print-link, .stats, .picker { display: none !important; }
  body::before { display: none; }

  /* Off-screen skipping is a scrolling optimisation; paginating needs every exercise laid out. */
  .group { content-visibility: visible; contain-intrinsic-height: none; }

  /* Paper is not glass. Frosting, shadows and rounded panes are dropped, and the clipping that
     rounds the heading band on screen has to go with them: an exercise longer than a page has to
     be able to fragment across pages, and `overflow: hidden` would cut it off instead. */
  .group, .group h2, .words.illustrated li, .thumb {
    border-radius: 0;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .group { overflow: visible; }
  .words.illustrated li, .thumb { background: transparent; }

  /* Unit header: dark badge, topic in caps, rule underneath - as in the book. */
  .top { display: block; margin: 0 0 4mm; padding-bottom: 2mm; border-bottom: 2.5pt solid #1b2a4a; }
  .eyebrow { display: block; color: #666; font-size: 8.5pt; letter-spacing: 1pt; text-shadow: none; }
  /* On screen the title sits on the black artwork and is white. On paper it would vanish. */
  h1 { margin: 1mm 0 0; color: #111; font-size: 18pt; text-transform: uppercase; letter-spacing: -.2pt; text-shadow: none; }
  .empty { color: #555; text-shadow: none; }

  /* A single unit prints its own running head on every page, so the block above it would just
     say the unit title twice on page one. */
  body[data-view="unit"] .top { display: none; }

  /* The running head: the table's own `thead`, which the browser repeats at the top of each page
     the table spans. Per unit, so the section booklet's head changes with the unit - which a
     `position: fixed` bar could not do. */
  .unit-print { display: table; width: 100%; }
  .unit-print > thead, .unit-print > thead.unit-head { display: table-header-group; }
  .unit-print > tbody, .unit-print > tbody.material { display: table-row-group; }
  .unit-print tr { display: table-row; }
  .unit-print th, .unit-print td { display: table-cell; }

  /* Only the booklet stacks units, and only there does a new unit start a new page. */
  .print-book .unit-print + .unit-print { break-before: page; }

  .unit-head { margin: 0; padding: 0; border: 0; }

  /* A pale bar rather than a rule: it repeats at the top of every page, so it should read as the
     book's running head at a glance without laying down a solid block of ink each time. */
  .unit-head-row {
    gap: 3mm;
    margin: 0 0 3.5mm;
    padding: 2mm 3mm;
    background: #eef1f6;
    color: #1b2a4a;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .unit-badge {
    width: 9mm;
    height: 9mm;
    background: #1b2a4a;
    color: #fff;
    font-size: 13pt;
  }
  .unit-where { color: #7a8aa0; font-size: 8pt; letter-spacing: .9pt; }
  .unit-name { font-size: 15pt; letter-spacing: -.1pt; }

  /* Each exercise sits in its own tinted box, a different hue per exercise type.
     print-color-adjust keeps the tints when the browser would otherwise drop backgrounds. */
  .group {
    margin: 0 0 4mm;
    padding: 2mm 2.5mm 1mm;
    border: 0.8pt solid #b9c3d2;
    border-radius: 0;
    background: #f4f6f9;
    break-inside: auto;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  /* An exercise short enough to fit a page is never split across two. Longer ones keep `auto`:
     forcing them whole would only leave a blank page before the break happens regardless. */
  .group.keep-whole { break-inside: avoid; }
  .group h2 { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .type-name { background: #fdf4e6; border-color: #e2c79a; }
  .type-match { background: #eef6ea; border-color: #b6d3a8; }
  .type-select { background: #eaf2fb; border-color: #a9c4e4; }
  .type-assist { background: #f5eef8; border-color: #cdb2d8; }
  .type-definition { background: #fdf0f0; border-color: #e3b3b3; }
  .type-translate { background: #f1f5fa; border-color: #b3c4d8; }
  .type-completeReverseTranslation { background: #edf6f1; border-color: #a9cdbb; }
  .type-partialReverseTranslate { background: #fbf4e9; border-color: #ddc79f; }
  .type-tapComplete { background: #f2f0fa; border-color: #bab3dd; }
  .type-gapFill { background: #fdf5ea; border-color: #e0c8a2; }
  .type-dialogue { background: #eaf6f6; border-color: #a6cece; }
  .type-readComprehension { background: #f7f4ec; border-color: #d6cbaa; }
  .type-story { background: #fbf1f4; border-color: #dcb3c0; }
  .group h2 {
    display: flex;
    align-items: center;
    gap: 2mm;
    margin: -2mm -2.5mm 2mm;
    padding: 1mm 2.5mm;
    background: rgba(27, 42, 74, .07);
    font-size: 10pt;
    text-transform: uppercase;
    letter-spacing: .3pt;
    break-after: avoid;
    break-inside: avoid;
  }
  .group-meta { display: none; }
  .type-icon { width: 4.5mm; height: 4.5mm; }
  .group h2 .type-icon { width: 7mm; height: 7mm; }

  /* Entries: tight leading, no card borders, dotted rule like a vocabulary list. */
  .words { display: block; }
  .words li, .sentences li, .readings li {
    display: block;
    padding: 0.7mm 0;
    border-bottom: 0.3pt dotted #bbb;
    break-inside: avoid;
  }
  /* The rule separates entries, so the last one has nothing to separate from - and its line would
     read as a second box edge just above the tinted box's own border. */
  .words li:last-child, .sentences li:last-child, .readings li:last-child { border-bottom: 0; }
  .words li { display: flex; gap: 3mm; align-items: baseline; justify-content: space-between; }
  .words .es, .sentences .es, .passage { font-size: 11.5pt; font-weight: 700; }
  .words .en, .sentences .en, .answer { color: #333; font-size: 10.5pt; font-weight: 400; }
  .sentences .en, .question, .answer { margin-top: 0.3mm; }
  .question { color: #555; font-size: 10pt; font-style: italic; }
  .story-lines .es { font-size: 11pt; }
  .story-lines .gloss { color: #666; font-size: 9pt; }
  .story-lines .speaker { color: #666; font-size: 8pt; }
  .group-meta, .question, .story-questions .question { color: #555; }
  .stories > li, .story-lines li { break-inside: avoid; }
  .es.feminine { color: #a11028; }

  /* Pictures stay, but small enough to keep the column dense. */
  .words.illustrated { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2.5mm; }
  .words.illustrated li { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1mm; aspect-ratio: 1; padding: 1.5mm 1mm; border: 0.5pt solid rgba(27, 42, 74, .2); text-align: center; overflow: hidden; }
  .words.illustrated .thumb { flex: 0 0 auto; width: 58%; height: auto; aspect-ratio: 1; }
  .words.illustrated .thumb img { width: 100%; height: 100%; object-fit: contain; }
  .words.illustrated .en { text-align: center; }
  .thumb, .thumb img { flex-basis: auto; width: 20mm; height: 20mm; }

  a { color: inherit; text-decoration: none; }
}

/* Stories: Duolingo's script with speaker names, glosses and comprehension questions. */
.stories > li { padding: 4px 0 14px; border-bottom: 1px solid var(--glass-edge); }
.story-title { margin: 0 0 10px; font-size: 18px; font-weight: 800; }
.story-lines { display: grid; gap: 9px; }
.story-lines li { display: grid; gap: 1px; }
.story-lines .speaker { color: var(--muted); font-size: 12px; font-weight: 900; letter-spacing: .6px; text-transform: uppercase; }
.story-lines .es { font-size: 17px; font-weight: 700; line-height: 1.3; }
.story-lines .gloss { color: var(--muted); font-size: 13px; font-weight: 500; }
.story-questions { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--glass-edge); display: grid; gap: 8px; }
.story-questions .question { color: var(--muted); font-size: 14px; font-weight: 800; }
.story-questions .answer { color: var(--lime-bright); font-size: 15px; font-weight: 700; }

/* ---------------------------------------------------------------------------
   Glass fallbacks. Without a backdrop filter the panes would be a wash of
   translucent white over the gradient with the text sitting on whatever shows
   through, so they go solid instead. Same when the reader has asked the system
   for less transparency.
   --------------------------------------------------------------------------- */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root {
    --glass: rgba(9, 26, 15, .94);
    --glass-strong: rgba(9, 26, 15, .98);
    --glass-line: rgba(200, 255, 150, .26);
  }
  .group[class*="type-"] { background: rgba(9, 26, 15, .94); }
}

@media (prefers-reduced-transparency: reduce) {
  :root {
    --glass: #0b1f13;
    --glass-strong: #102a1a;
    --glass-line: rgba(200, 255, 150, .28);
  }
  body::before { background: #061a0e; }
  .navbar, .trail, .group, .picker a, .print-row button {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .group[class*="type-"] { background: #0b1f13; }
}

/* Phone. Declared here, at the end, because `.picker` and `.words.illustrated` are defined below
   the breakpoints above and would otherwise win on source order at equal specificity. */
@media (max-width: 460px) {
  .words:not(.illustrated) li { flex-wrap: wrap; }
  .words:not(.illustrated) .en { text-align: left; }
  .words.illustrated { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
}

/* Section and unit buttons are the whole navigation on a phone, so they take the full width and
   are hit without aiming. A tablet fits two; only a desktop packs them by size. */
@media (max-width: 719px) {
  .picker, .picker.units { grid-template-columns: 1fr; }
  .picker a { min-height: 84px; }
  .picker.named a { min-height: 92px; }
}
@media (min-width: 720px) and (max-width: 1023px) {
  .picker, .picker.units { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
