/* Brandon Anthony: the resume and its case studies, on one page.
   Colours are tokens, once for day and once for night (twice, in fact: once for the system
   setting and once for the toggle's explicit choice). Every text pair passes WCAG AA in
   both themes; README lists the measured ratios. Vermilion (--shu) is used for shapes only
   (in this file, the current roles' log marks; the sword's grip wrap carries the same
   colour in its own SVG), never for text: on the night ground it is 3.5:1, enough for a
   shape and not for words. An open case study is marked in ink, not vermilion. */

:root {
  color-scheme: light;
  --paper: #f3eee3;     /* washi */
  --card: #fbf8f1;
  --tint: #ebe5d7;      /* an open case study's control, the code snippets */
  --ink: #1d1b18;       /* sumi */
  --muted: #5b5548;     /* 6.4:1 on paper, 5.7:1 on tint */
  --line: #d6cdb9;      /* hairlines; decorative only */
  --edge: #8a8170;      /* control borders, 3.3:1 */
  --shu: #c23a22;       /* vermilion: shapes only */
  --ai: #1f4a73;        /* indigo: links, focus, the primary button */
  --on-ai: #f3eee3;
  --slash: rgba(29, 27, 24, .42);
  --grain: url(/washi.svg);
  --moon: none;
  --icon-moon: inline-block;
  --icon-sun: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #0e1322;   /* night: indigo-black */
    --card: #151b2e;
    --tint: #1c2440;
    --ink: #ebe7dc;     /* moon-white */
    --muted: #a3a9b8;
    --line: #262e47;
    --edge: #66708a;
    --shu: #c23a22;
    --ai: #93b4e0;
    --on-ai: #0e1322;
    --slash: rgba(235, 231, 220, .36);
    --grain: none;
    --moon: block;
    --icon-moon: none;
    --icon-sun: inline-block;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #0e1322;
  --card: #151b2e;
  --tint: #1c2440;
  --ink: #ebe7dc;
  --muted: #a3a9b8;
  --line: #262e47;
  --edge: #66708a;
  --shu: #c23a22;
  --ai: #93b4e0;
  --on-ai: #0e1322;
  --slash: rgba(235, 231, 220, .36);
  --grain: none;
  --moon: block;
  --icon-moon: none;
  --icon-sun: inline-block;
}

/* --- Base ---------------------------------------------------------------------------- */

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

/* An author "display" rule beats the browser's own [hidden] rule, so every element given
   display:flex or inline-flex below would ignore its hidden attribute without this. */
[hidden] { display: none !important; }

/* A name that must not break: "S-RM" would otherwise wrap at its hyphen, and an employer's
   two words ("Coalfire Federal") belong on one line. */
.nw { white-space: nowrap; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--paper);
}

/* min-height: the paper texture is the body's background, so on a page shorter than the
   window (the 404 page) it would stop where the body ends and flat colour would carry on
   below it, a visible seam. */
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--paper);
  background-image: var(--grain);
  color: var(--ink);
  font: 400 1.0625rem/1.6 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, .display {
  font-family: 'Shippori Mincho B1', Georgia, 'Times New Roman', serif;
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}

p { margin: 0 0 1em; text-wrap: pretty; }

a { color: var(--ai); text-decoration-thickness: 1px; text-underline-offset: .2em; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible { outline: 3px solid var(--ai); outline-offset: 3px; border-radius: 2px; }
main:focus { outline: none; }

img { max-width: 100%; }

.wrap {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding-inline: 16px;
}
@media (min-width: 640px) { .wrap { padding-inline: 24px; } }
@media (min-width: 1024px) { .wrap { padding-inline: 32px; } }

.skip {
  position: absolute;
  left: 16px;
  top: -200px;
  z-index: 10;
  padding: 12px 16px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 4px;
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { top: 12px; }

.label {
  margin: 0 0 14px;
  font: 500 .75rem/1.3 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 20px;
}
@media (min-width: 640px) { .card { padding: 24px 28px; } }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 18px;
  border-radius: 4px;
  border: 1px solid var(--edge);
  background: transparent;
  color: var(--ink);
  font: 500 .9375rem/1.2 'IBM Plex Sans', system-ui, sans-serif;
  text-decoration: none;
  cursor: pointer;
}
.btn:hover { border-color: var(--ai); color: var(--ai); }
.btn-primary { background: var(--ai); border-color: var(--ai); color: var(--on-ai); }
.btn-primary:hover { color: var(--on-ai); text-decoration: underline; }

/* --- Header -------------------------------------------------------------------------- */

.top { border-bottom: 1px solid var(--line); }
.top-row { display: flex; align-items: center; gap: 8px; min-height: 64px; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  min-width: 44px;
  margin-right: auto;
  color: var(--ink);
  text-decoration: none;
}
/* The sword is decoration (alt="" and aria-hidden): the name beside it is the link text. */
.brand-mark { display: block; flex: none; width: 40px; height: 40px; }
.brand-name {
  font-family: 'Shippori Mincho B1', Georgia, 'Times New Roman', serif;
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: .01em;
  white-space: nowrap;
}

/* Contact is in the header at every width: a hiring manager opening this from LinkedIn or
   an email is usually on a phone, and without it the only way to the contact details was
   to scroll ten thousand pixels. The other three links join it once they fit. */
.nav { display: flex; gap: 2px; }
.nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  color: var(--ink);
  font-size: .9375rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.nav a:hover { color: var(--ai); text-decoration: underline; text-underline-offset: 6px; }
.nav .nav-wide { display: none; }
/* From 840px all four fit on one line beside the name and the toggle ("Case studies" is
   the long one; at 760 it wrapped to two lines). */
@media (min-width: 840px) {
  .nav { margin-right: 8px; }
  .nav .nav-wide { display: inline-flex; }
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  min-width: 44px;
  padding: 0 14px;
  border: 1px solid var(--edge);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  font: 500 .875rem/1 'IBM Plex Sans', system-ui, sans-serif;
  cursor: pointer;
}
.theme-toggle:hover { border-color: var(--ai); }
/* On a phone the header holds the sword, the name, Contact and this button, and the word
   does not fit beside them; the button keeps its icon and its accessible name ("Switch to
   night theme"). Below 360px the name leaves the screen but not the page: it is the home
   link's only text, so it is clipped rather than removed, and the link keeps its name. */
@media (max-width: 479px) { .theme-toggle { padding: 0 12px; } .theme-text { display: none; } }
@media (max-width: 359px) { .brand-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } }
.icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.icon-moon { display: var(--icon-moon); }
.icon-sun { display: var(--icon-sun); }

/* --- Hero ---------------------------------------------------------------------------- */

/* The name, then straight to "At a glance": nothing else sits under the name. */
.hero { position: relative; overflow: hidden; padding: 44px 0 48px; }
@media (min-width: 960px) { .hero { padding: 72px 0 64px; } }
.hero .wrap { position: relative; }

.eyebrow {
  margin: 0 0 18px;
  font: 500 .8125rem/1.5 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}

h1 {
  margin: 0 0 28px;
  font-size: clamp(2.625rem, 1.9rem + 3.6vw, 4.75rem);
  line-height: 1.02;
  letter-spacing: -.012em;
}

/* The 404 page's one line under its heading. */
.lead {
  max-width: 30em;
  margin: 0 0 16px;
  font-size: clamp(1.125rem, 1rem + .5vw, 1.375rem);
  line-height: 1.45;
}

/* Night only: a faint crescent, drawn as the part of an offset shadow that the circle's
   own box does not cover (a box never paints its outer shadow underneath itself). The
   soft moonlight around it is a separate radial gradient, so no glow is clipped into a
   dark disc. It sits beside the name, above the "At a glance" card, never behind it. */
.moon {
  display: var(--moon);
  position: absolute;
  top: 14px;
  right: max(20px, calc(50% - 600px));
  width: 72px;
  height: 72px;
  border-radius: 50%;
  box-shadow: 15px -8px 0 0 rgba(235, 231, 220, .15);
  pointer-events: none;
}
.moon::before {
  content: "";
  position: absolute;
  inset: -70px -50px -50px -30px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(147, 180, 224, .07), transparent);
}
/* The narrowest phones: smaller, higher and further right, so the lower tip clears the end
   of the eyebrow's first line. It grows once the name has the width to itself.
   The crescent is the shadow, which sits right of the box by its x offset, so "right" must
   be larger than that offset or the hero's overflow cuts the outer curve flat at the
   window's edge: from 960 to 1246px a 20px right with a 24px offset cut 4px off, and below
   360px the tip touched the edge. The same holds for "top" and the upward offset: below
   360px a 2px top with a 6px lift cut the upper tip off at the header line. Each size now
   keeps clear of both edges. */
@media (max-width: 359px) { .moon { top: 8px; right: 16px; width: 52px; height: 52px; box-shadow: 11px -6px 0 0 rgba(235, 231, 220, .15); } }
@media (min-width: 960px) { .moon { top: 36px; right: max(32px, calc(50% - 600px)); width: 110px; height: 110px; box-shadow: 24px -12px 0 0 rgba(235, 231, 220, .15); } }

.glance { position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 4px; padding: 20px 20px 16px; }
@media (min-width: 640px) { .glance { padding: 24px 28px 20px; } }

/* Six entries: one column on a phone (the names are long and read best whole), two from
   600px, three from 960px, so the laptop sees two even rows. */
.facts { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr; column-gap: 32px; }
@media (min-width: 600px) { .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 960px) { .facts { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.facts li { padding: 14px 0 16px; border-top: 1px solid var(--line); }
.fig {
  display: block;
  margin-bottom: 4px;
  font-family: 'Shippori Mincho B1', Georgia, 'Times New Roman', serif;
  font-weight: 700;
  font-size: clamp(1.125rem, 1.02rem + .45vw, 1.3125rem);
  line-height: 1.3;
}
/* The line under each entry: a direct child, so the no-break spans inside the employers
   entry are left alone. */
.facts li > span { display: block; font-size: .875rem; line-height: 1.45; color: var(--muted); }
/* Founder of Otti leads the card with Otti's own mark, small, in its own colours: it is
   Otti's logo, not the site's, so it keeps its cream tile on both grounds. Decorative
   (alt=""): the words beside it already say Otti. */
.fig-mark { display: flex; align-items: center; gap: 10px; }
.otti-mark-sm { flex: none; width: 24px; height: 24px; border-radius: 23%; box-shadow: 0 0 0 1px var(--line); }
.reviewed { margin: 4px 0 0; padding-top: 12px; border-top: 1px solid var(--line); font-size: .8125rem; color: var(--muted); }

/* --- Brush dividers ------------------------------------------------------------------ */
/* One thin stroke between sections: a brush shape, revealed along its own centre line by a
   mask whose stroke is drawn with stroke-dashoffset. Drawn by default; site.js arms it
   (hidden) and draws it once as it comes into view. */

.divider { max-width: 1080px; margin: 0 auto; padding-inline: 16px; color: var(--slash); }
/* Subtle on purpose: a line between sections, not a picture. */
@media (min-width: 640px) { .divider { padding-inline: 24px; } }
@media (min-width: 1024px) { .divider { padding-inline: 32px; } }
/* A cut, not a pen line: a fast start and a hard stop. Every other divider is mirrored so
   five identical strokes do not turn into wallpaper; the mask flips with the shape, so a
   mirrored stroke still draws from its sharp head. Dividers are the only divs that are
   children of <main>, which is what makes nth-of-type count them alone. */
.slash { display: block; width: 100%; height: auto; aspect-ratio: 1000 / 56; overflow: visible; }
.divider:nth-of-type(even) .slash { transform: scaleX(-1); }
.slash .brush { fill: currentColor; }
.slash .reveal { fill: none; stroke: #fff; stroke-width: 14; stroke-linecap: butt; stroke-dasharray: 1 1; stroke-dashoffset: 0; }
.divider.is-armed .reveal { stroke-dashoffset: 1; }
.divider.is-armed.is-drawn .reveal { stroke-dashoffset: 0; transition: stroke-dashoffset .45s cubic-bezier(.16, 1, .3, 1); }

/* --- Sections ------------------------------------------------------------------------ */

.sec { padding: 52px 0; }
@media (min-width: 960px) { .sec { padding: 64px 0 72px; } }

.sec-head { margin-bottom: 28px; }
.sec-head h2 { margin: 0; font-size: clamp(1.875rem, 1.45rem + 1.5vw, 2.625rem); line-height: 1.1; }

.sec-intro { max-width: 40em; margin: -10px 0 28px; color: var(--muted); }

/* Overview */
.overview-grid { display: grid; gap: 28px; }
@media (min-width: 960px) { .overview-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 48px; align-items: start; } }
.prose p { max-width: 38em; }
.prose p:first-child { font-size: 1.125rem; }
.scope h3 { margin: 0 0 14px; font-size: 1.25rem; }
.scope dl { margin: 0; }
.scope dt { font-weight: 600; font-size: .9375rem; }
.scope dd { margin: 2px 0 14px; color: var(--muted); font-size: .9375rem; line-height: 1.55; }
.scope dd:last-child { margin-bottom: 0; }

/* --- Experience: the evidence log ---------------------------------------------------- */
/* The role is first in the source, so a screen reader's heading list lands on it; the
   period is placed in the left column only by the grid. */

.log { list-style: none; margin: 0; padding: 0; }
.log-entry { position: relative; padding: 0 0 36px 24px; border-left: 1px solid var(--line); }
.log-entry:last-child { padding-bottom: 4px; }
.log-entry::before {
  content: "";
  position: absolute;
  left: -5px;
  top: .55em;
  width: 9px;
  height: 9px;
  background: var(--paper);
  border: 1px solid var(--ink);
}
.log-entry.is-current::before { background: var(--shu); border-color: var(--shu); }
.log-entry h3 { margin: 0 0 4px; font-size: 1.25rem; }
.log-entry .org { font-weight: 500; color: var(--muted); }
.log-period {
  margin: 0 0 12px;
  font: 500 .8125rem/1.5 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
}
.log-ev { margin: 0; padding-left: 1.1em; list-style: square; }
.log-ev li { margin-bottom: 6px; padding-left: 2px; }
.log-ev li::marker { color: var(--muted); }
/* A link on a line of its own is a touch target, so it gets the 44px every other control
   has; the extra height sits above and below the words, and the margins below give that
   space back so the words stay where they were. */
.log-link { margin: 0; }
.log-link a { display: inline-flex; align-items: center; min-height: 44px; }

@media (min-width: 900px) {
  .log-entry {
    display: grid;
    /* The text column stops at about 75 characters; the date column is as wide as the
       longest period ("January 2025 – January 2026"), so no date wraps. */
    grid-template-columns: 15.5rem minmax(0, 40rem);
    grid-template-areas: "period title" "period ev" "period link";
    padding: 0;
    border-left: 0;
  }
  .log-entry::before { left: calc(15.5rem - 4px); }
  .log-entry h3 { grid-area: title; padding-left: 36px; border-left: 1px solid var(--line); margin: 0; padding-bottom: 8px; }
  .log-period { grid-area: period; padding-top: .3em; margin: 0; }
  .log-ev { grid-area: ev; margin: 0; padding: 0 0 36px calc(36px + 1.1em); border-left: 1px solid var(--line); }
  .log-link { grid-area: link; margin: -35px 0 0; padding: 0 0 25px 36px; border-left: 1px solid var(--line); }
  .log-entry:last-child .log-ev { padding-bottom: 4px; }
}

/* --- Case studies ------------------------------------------------------------------- */
/* Otti first, as it was set up (always open), then four studies, each a short summary
   with the full study in a <details>: it opens with no script, says it is collapsed or
   expanded to a screen reader, and keeps the page short for someone scanning. */

.case + .case { margin-top: 48px; padding-top: 40px; border-top: 1px solid var(--line); }
@media (min-width: 960px) { .case + .case { margin-top: 56px; padding-top: 48px; } }
.case-kicker {
  margin: 0 0 10px;
  font: 500 .75rem/1.3 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.case > h3, .case-title h3 { margin: 0 0 12px; font-size: clamp(1.5rem, 1.25rem + 1vw, 2rem); line-height: 1.15; max-width: 24em; }
/* Otti's own mark, exactly as Otti's site draws it (its cream tile included), beside the
   word "Otti": a product in a case study, never the owner's logo, which is the sword in
   the header. The hairline ring gives the cream tile an edge on the day paper. */
.case-title { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.case-title h3 { margin: 0; }
.otti-mark { display: block; flex: none; width: 40px; height: 40px; border-radius: 23%; box-shadow: 0 0 0 1px var(--line); }
.case-dek { max-width: 38em; margin: 0 0 12px; font-size: 1.125rem; line-height: 1.5; color: var(--muted); }
.case-hook { max-width: 40em; margin: 0 0 4px; }

.case-more { margin-top: 20px; }
.case-more > summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 16px 10px 14px;
  border: 1px solid var(--edge);
  border-radius: 4px;
  background: var(--card);
  color: var(--ink);
  font-weight: 500;
  font-size: .9375rem;
  line-height: 1.3;
  list-style: none;
  cursor: pointer;
}
.case-more > summary::-webkit-details-marker { display: none; }
.case-more > summary:hover { border-color: var(--ai); color: var(--ai); }
.case-more[open] > summary { background: var(--tint); border-color: var(--ink); }
.more-icon { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.more-icon .v { transform-box: fill-box; transform-origin: center; transition: transform .2s ease; }
.case-more[open] .more-icon .v { transform: scaleY(0); }
.more-close { display: none; }
.case-more[open] .more-open { display: none; }
.case-more[open] .more-close { display: inline; }
/* The study's title, for a screen reader moving from control to control: four "Read the
   full case study" buttons would otherwise sound the same. */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The full study: on a wide screen, the story and the proof down the left, what I did in
   a card on the right, as the Otti block does. Source order is the copy's order. */
.case-body { display: grid; gap: 28px; margin-top: 28px; }
@media (min-width: 960px) {
  .case-body {
    grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
    grid-template-areas: "story did" "proof did";
    grid-template-rows: auto 1fr;
    column-gap: 48px;
    row-gap: 28px;
  }
  .case-story { grid-area: story; }
  .case-did { grid-area: did; align-self: start; }
  .case-proof { grid-area: proof; }
}
.case-body h4 { margin: 0 0 10px; font-size: 1.1875rem; }
.case-body p { max-width: 38em; }
.case-story p + h4, .case-story p + p + h4 { margin-top: 24px; }
.case-body > div > :last-child { margin-bottom: 0; }
.lesson { margin: 20px 0 0; padding-top: 14px; border-top: 2px solid var(--ink); }

/* The snippets wrap rather than scroll, so a phone reads them whole and the page never
   moves sideways: each line is its own block, and a wrapped line hangs under its start.
   On a narrow screen the long alignment runs of spaces shrink to a short indent. */
.snippet {
  margin: 18px 0 0;
  padding: 12px 14px;
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink);
  font: 500 .8125rem/1.6 'IBM Plex Mono', ui-monospace, monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.snippet code { font: inherit; }
.snippet .ln { display: block; padding-left: 4ch; text-indent: -4ch; }
@media (max-width: 599px) {
  .snippet .pad { display: inline-block; width: 4ch; overflow: hidden; vertical-align: top; white-space: pre; }
}

.chips { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: -8px 0 28px; padding: 0; }
.chips li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--edge);
  border-radius: 4px;
  background: var(--card);
  font-size: .8125rem;
  font-weight: 500;
}
.chip-live::before { content: ""; width: 7px; height: 7px; background: var(--ai); }

/* The source order is the copy's order: the story, how it is governed, then the stack
   line, the note and the links. On a wide screen the grid puts that last group under the
   story, beside the governance card, instead of below both. */
.otti-grid { display: grid; gap: 28px; }
@media (min-width: 960px) {
  .otti-grid {
    grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
    grid-template-areas: "story gov" "foot gov";
    grid-template-rows: auto 1fr;
    column-gap: 48px;
    row-gap: 8px;
  }
  .otti-story { grid-area: story; }
  .otti-gov { grid-area: gov; align-self: start; }
  .otti-foot { grid-area: foot; align-self: start; }
}
.otti-story h4, .otti-gov h4 { margin: 0 0 10px; font-size: 1.1875rem; }
.otti-story p { max-width: 36em; }
.otti-story p + h4 { margin-top: 24px; }
.otti-story p:last-child { margin-bottom: 0; }
.stack { margin: 0 0 14px; padding-top: 14px; border-top: 1px solid var(--line); color: var(--muted); font-size: .9375rem; }

.controls { list-style: none; margin: 0; padding: 0; }
.controls li { position: relative; padding: 12px 0 12px 22px; border-top: 1px solid var(--line); }
.controls li:last-child { padding-bottom: 0; }
.controls li::before { content: ""; position: absolute; left: 2px; top: 1.3em; width: 7px; height: 7px; background: var(--ink); }
.controls strong { font-weight: 600; }

.otti-foot { max-width: 36em; }
.otti-foot .note { margin: 0 0 14px; font-size: .875rem; color: var(--muted); }
.otti-foot .links { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; }

/* --- Certifications and education ---------------------------------------------------- */

.cred-grid { display: grid; gap: 16px; }
@media (min-width: 760px) { .cred-grid { grid-template-columns: 1fr 1fr; gap: 24px; } }
.cred-grid h3 { margin: 0 0 12px; font-size: 1.25rem; }
.cred { list-style: none; margin: 0; padding: 0; }
.cred li { padding: 10px 0; border-top: 1px solid var(--line); font-weight: 500; }
.cred li:last-child { padding-bottom: 0; }
.cred .by { font-weight: 400; color: var(--muted); }

/* --- Contact ------------------------------------------------------------------------- */

.contact-lead { max-width: 36em; font-size: 1.125rem; }
.contact-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px 16px; }
.email { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.email-nojs { margin: 0; padding-top: 10px; font-size: .9375rem; color: var(--muted); max-width: 30em; }
.email-revealed { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.email-addr {
  font: 500 1.0625rem/1.4 'IBM Plex Mono', ui-monospace, monospace;
  padding: 9px 0;
  overflow-wrap: anywhere;
}
.email-buttons { display: inline-flex; gap: 10px; }
.email-status { margin: 0; min-height: 1.5em; font-size: .875rem; color: var(--muted); }

/* --- Footer -------------------------------------------------------------------------- */

.foot { border-top: 1px solid var(--line); padding: 24px 0 32px; }
.foot p { margin: 0; font-size: .875rem; color: var(--muted); }

/* --- 404 ----------------------------------------------------------------------------- */

.missing { padding: 56px 0 96px; }
.missing-mark { display: block; width: 72px; height: 72px; margin-bottom: 24px; }
.missing h1 { font-size: clamp(2.25rem, 1.7rem + 2.6vw, 3.5rem); }
.missing .lead { color: var(--muted); }

/* --- Motion and print ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .divider .reveal { stroke-dashoffset: 0 !important; transition: none !important; }
}

/* Paper is always day. The selector list has to match the night blocks' specificity: a
   plain :root here lost to :root[data-theme="dark"] and to the system-setting block, and a
   visitor in the night theme printed faint moon-white text on a dark ground. */
@media print {
  :root, :root[data-theme="dark"], :root:not([data-theme="light"]) {
    color-scheme: light;
    --paper: #fff; --card: #fff; --tint: #fff; --ink: #000; --muted: #333; --line: #ccc; --edge: #666;
    --ai: #000; --on-ai: #fff; --grain: none; --moon: none; --slash: #999;
  }
  .skip, .nav, .theme-toggle, .divider, .more-icon, .email { display: none !important; }
  /* site.js opens every case study for printing; an open one needs no control on paper. */
  .case-more[open] > summary { display: none; }
  /* A printed copy still needs a way to reach the owner. The email stays out of the page
     source, so LinkedIn carries it, with its address written out. */
  /* The link is a flex box, which drops a leading space in generated content: hence the margin. */
  .contact-actions a[href^="https://www.linkedin.com/"]::after { content: "(" attr(href) ")"; margin-left: .35em; }
  .btn-primary { background: transparent; color: #000; border-color: #000; }
  .snippet { background: transparent; }
  .sec { padding: 24px 0; }
  a { color: #000; }
}
