/*
 * Nate theme styles. Values come from theme.json presets (the Figma tokens); sizes that have no token
 * in Figma (the 150px header, the 230x150 folder cover, the 997px hero image) are named below.
 *
 * 1 Base   2 Header and footer   3 Breadcrumb   4 Home folders   5 Work folder
 * 6 Work page   7 Text page   8 Placeholders   9 Small screens
 */

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

:root {
  --page-x: var(--wp--preset--spacing--5-xl); /* 96px on a 1440 screen, 24px on a phone */
  --black: var(--wp--preset--color--black);
  --muted: var(--wp--preset--color--muted);
  --grey: var(--wp--preset--color--placeholder);
  --focus: 2px solid var(--black);
}

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

/* A double tap no longer zooms the page on phones (owner, 2026-11-01); a pinch still does, for anyone
   who needs the text bigger (iPhone ignores a full zoom lock anyway). On every element, because
   touch-action is not inherited. */
* {
  touch-action: manipulation;
}

body {
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
p,
ul,
ol,
dl,
figure {
  margin: 0;
}

/* Nicer line breaks (owner, 2026-10-30): running text never leaves one word alone on its last line,
   and headings and short labels even out their lines. Browsers without support wrap as before. */
p,
li,
dd {
  text-wrap: pretty;
}

h1,
h2,
h3,
figcaption,
.experience-row,
.work-thumb-text,
.folder-label,
.caption-title {
  text-wrap: balance;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* The display rules above must not show what the hidden attribute hides (the other slides). */
[hidden] {
  display: none !important;
}

a {
  color: inherit;
  text-decoration: none;
  text-underline-offset: 4px;
  transition: color 0.2s ease;
}

/* Hover changes the colour, never adds an underline (owner, 2026-10-27). Underlines mark state
   only: the current page in the nav. The open experience row is black instead (owner, 2026-10-30). */
a:hover {
  color: var(--muted);
}

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

::selection {
  background: var(--black);
  color: var(--wp--preset--color--white);
}

.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--page-x);
  z-index: 10;
  padding: 8px 16px;
  background: var(--black);
  color: var(--wp--preset--color--white);
}

.skip-link:focus {
  top: 8px;
}

.skip-link:hover {
  color: var(--wp--preset--color--white);
}

/* 2 Header and footer ------------------------------------------------------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wp--preset--spacing--md);
  min-height: 150px;
  padding: 0 var(--page-x);
}

.wordmark {
  display: block;
  line-height: 0;
}

.wordmark svg {
  display: block;
  width: auto;
  height: 36px;
}

.tagline {
  width: 400px; /* two lines with the name in it (2026-11-01) */
  font-size: var(--wp--preset--font-size--md);
  font-weight: 600;
  line-height: normal;
}

.site-nav ul {
  display: flex;
  gap: var(--wp--preset--spacing--md);
  line-height: normal;
}

.site-nav [aria-current="page"] {
  text-decoration: underline;
}

.site-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wp--preset--spacing--md);
  min-height: 163px;
  padding: var(--wp--preset--spacing--md) var(--page-x);
  line-height: normal;
}

.connect-box {
  display: flex;
  flex-wrap: wrap;
  gap: var(--wp--preset--spacing--md) var(--wp--preset--spacing--3-xl);
}

/* 3 Breadcrumb ("Location", Figma 105:80) ------------------------------------------------------------ */

.crumbs {
  padding: var(--wp--preset--spacing--2-xl) var(--page-x);
}

.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--md);
}

.crumbs li {
  display: flex;
  align-items: center;
  gap: var(--wp--preset--spacing--md);
}

.crumb {
  display: flex;
  align-items: center;
  gap: var(--wp--preset--spacing--md);
  font-size: var(--wp--preset--font-size--xs);
  line-height: normal;
}

/* Line icons from nate_mini_icon(), centred in the 31px slot the Figma chips use. */
.crumb-icon {
  flex: none;
  box-sizing: content-box;
  padding: 0 calc((31px - 24px) / 2);
}

.crumb .crumb-icon[width="18"] {
  padding: 0 calc((31px - 18px) / 2);
}

.crumb-arrow {
  flex: none;
}

/* 4 Home folders (Figma 43:497) ------------------------------------------------------------------- */

.folders {
  padding: calc(var(--wp--preset--spacing--4-xl) + var(--wp--preset--spacing--2-xl)) var(--page-x) var(--wp--preset--spacing--4-xl);
}

.folder-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--2-xl) var(--wp--preset--spacing--4-xl);
  max-width: 1248px;
  margin: 0 auto;
}

.folder a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--wp--preset--spacing--xs);
}

.folder a:hover {
  text-decoration: none;
}

/* Folder icon, flat two-tone (owner picked style D, 2026-10-27): a darker back panel with a tab, a
   sheet of paper inside (a work folder's cover peeks out on it) and a lighter front panel. No
   gradients, shadows or tilt. Sizes are percentages of the 230x150 box, so it scales on small
   screens. On hover the paper rises and the front drops a little. */
.icon-folder {
  position: relative;
  display: block;
  width: 230px;
  aspect-ratio: 230 / 150;
}

.icon-folder-back {
  position: absolute;
  inset: 9% 0 0;
  border-radius: 6px 8px 8px 8px;
  background: #c4c5c6;
}

.icon-folder-back::before {
  content: "";
  position: absolute;
  top: -10%;
  left: 0;
  width: 38%;
  height: 14%;
  border-radius: 6px 6px 0 0;
  background: #c4c5c6;
  clip-path: polygon(0 0, 80% 0, 100% 100%, 0 100%);
}

.icon-folder-paper {
  position: absolute;
  top: 2%;
  left: 7%;
  right: 7%;
  aspect-ratio: 16 / 9; /* the cover's own shape, so the whole screen fits (owner, 2026-10-27) */
  overflow: hidden;
  border-radius: 3px;
  background:
    repeating-linear-gradient(180deg, transparent 0 16%, #ececec 16% 19%) 12% 40% / 76% 50% no-repeat,
    var(--wp--preset--color--white);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

/* A 16:9 website cover fills the paper whole; a 4:5 photo cover fills it from its middle instead of
   showing as a thin strip (2026-10-28). */
.icon-folder-paper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.icon-folder-front {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 52%; /* low enough that most of the cover shows (HR panel, 2026-10-31; was 74%) */
  border-radius: 5px 5px 8px 8px;
  background: #e3e4e5;
}

/* .is-open: the same on a phone, where main.js plays it on a tap before opening the folder (2026-11-01). */
.folder a:hover .icon-folder-paper,
.folder a:focus-visible .icon-folder-paper,
.folder a.is-open .icon-folder-paper {
  transform: translateY(-35%); /* high enough to show most of the cover, the Giraffe uncle's eyes included (owner, 2026-11-01; was -12%) */
}

/* Document icon, same flat greys: one sheet with a folded corner, lines for text and a heading bar,
   the same resume sheet for every document. No second sheet behind it: it read as a shadow and
   crowded the label (owner, 2026-10-27). */
.icon-doc {
  position: relative;
  display: block;
  width: 150px;
  aspect-ratio: 150 / 200;
  container-type: inline-size; /* 22cqw below = the fold, 22% of the sheet's width */
}

.icon-doc-sheet {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  background:
    repeating-linear-gradient(180deg, #e3e4e5 0 3px, transparent 3px 14px) 50% 86% / 70% 46% no-repeat,
    #f4f4f5;
  /* The corner is really cut away, not painted page-white, so it holds on any background
     (it showed while the page faded back from the dark theme, owner 2026-10-30). */
  clip-path: polygon(0 0, calc(100% - 22cqw) 0, 100% 22cqw, 100% 100%, 0 100%);
  transition: clip-path 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

/* The folded corner: a grey flap under the cut. */
.icon-doc-sheet::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 22%;
  aspect-ratio: 1;
  border-bottom-left-radius: 4px;
  background: linear-gradient(225deg, transparent 50%, #c4c5c6 50%);
  transform-origin: top right;
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.icon-doc-sheet::before {
  content: "";
  position: absolute;
  top: 12%;
  left: 15%;
  width: 34%;
  height: 7%;
  border-radius: 2px;
  background: #cfcfcf;
}

/* Hover unfolds the corner; the sheet itself stays still (owner, 2026-10-30). */
.folder a:hover .icon-doc-sheet::after,
.folder a:focus-visible .icon-doc-sheet::after,
.folder a.is-open .icon-doc-sheet::after {
  transform: scale(0);
}

.folder a:is(:hover, :focus-visible, .is-open) .icon-doc-sheet {
  clip-path: polygon(0 0, 100% 0, 100% 0, 100% 100%, 0 100%);
}

.folder-label {
  display: flex;
  align-items: center;
  gap: var(--wp--preset--spacing--xs);
  font-size: var(--wp--preset--font-size--lg);
  line-height: normal;
}

.folder a:is(:hover, .is-open) .folder-label {
  color: var(--muted);
}

.dot {
  width: 10px;
  height: 10px;
}

/* 5 Work folder (Figma 50:947) --------------------------------------------------------------------- */

.work-folder {
  padding: var(--page-x);
}

.work-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--5-xl);
}

.work-thumb a {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--sm);
  text-align: center;
}

.work-thumb a:hover {
  text-decoration: none;
}

/* Covers are 16:9 screenshots, shown whole like a desktop screen and never cropped (owner,
   2026-10-27). A cover of another shape fits inside the frame instead of losing its edges. */
.work-thumb-image,
.work-thumb .placeholder {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: contain;
  transition: transform 0.25s ease;
}

/* Photo covers are 4:5, the shape the photos are shot in (owner, 2026-10-28). */
.term-photography .work-thumb-image,
.term-photography .work-thumb .placeholder {
  aspect-ratio: 4 / 5;
}

/* Hover grows the cover a little instead of lifting it (owner, 2026-10-30). */
.work-thumb a:hover .work-thumb-image {
  transform: scale(1.01);
}

.work-thumb-text {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--xs);
  line-height: normal;
}

.work-thumb-name {
  font-size: var(--wp--preset--font-size--lg);
}

.work-thumb a:hover .work-thumb-name {
  color: var(--muted);
}

.work-thumb-count,
.work-thumb-desc {
  font-size: var(--wp--preset--font-size--xs);
  color: var(--muted);
}

.empty-note {
  color: var(--muted);
}

/* Website Design and its projects are dark, so the sites glow like lit screens (owner, 2026-10-29).
   header.php adds screen-enter on the way in (white dims to dark) and screen-leave on the way out to
   a light page (dark brightens to white). The colours are registered so they fade, not jump. */
@property --screen-ink {
  syntax: "<color>";
  inherits: true;
  initial-value: #000;
}

@property --screen-paper {
  syntax: "<color>";
  inherits: true;
  initial-value: #fff;
}

@property --screen-glow {
  syntax: "<color>";
  inherits: true;
  initial-value: transparent;
}

@property --screen-muted {
  syntax: "<color>";
  inherits: true;
  initial-value: #595959;
}

.screen-dark,
.screen-leave body {
  --black: var(--screen-ink);
  --muted: var(--screen-muted);
  background: var(--screen-paper);
  color: var(--screen-ink);
}

.screen-dark {
  --screen-ink: #fff;
  --screen-paper: #111;
  --screen-muted: #a6a6a6; /* 7:1 on the dark page; the light grey would fail */
  --screen-glow: rgb(255 255 255 / 0.1); /* soft: the owner found 0.22 too strong */
}

.screen-dark ::selection {
  background: var(--screen-ink);
  color: var(--screen-paper);
}

/* Filled black buttons turn white here, so their text turns dark. */
.screen-dark :is(.skip-link, .skip-link:hover, .caption-nav button:hover) {
  color: var(--screen-paper);
}

/* Each site glows at its edge like a lit screen (owner, 2026-10-29), a little brighter on hover. */
.screen-dark .work-thumb-image {
  outline: 1px solid rgb(255 255 255 / 0.12); /* the edge of a dark site still shows */
  box-shadow: 0 0 24px var(--screen-glow);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.screen-dark .work-thumb a:hover .work-thumb-image {
  box-shadow: 0 0 32px 2px var(--screen-glow);
}

@media (prefers-reduced-motion: no-preference) {
  .screen-enter .screen-dark {
    animation: screen-dim 1.2s ease 0.3s backwards;
  }

  .screen-leave body {
    animation: screen-undim 1s ease 0.15s backwards;
  }
}

@keyframes screen-dim {
  from {
    --screen-ink: #000;
    --screen-paper: #fff;
    --screen-muted: #595959;
    --screen-glow: transparent;
  }
}


@keyframes screen-undim {
  from {
    --screen-ink: #fff;
    --screen-paper: #111;
    --screen-muted: #a6a6a6;
  }
}


/* 6 Work page (Figma 51:1129 website, 77:384 graphic and photography) -------------------------------- */

.work {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--2-xl);
}

.work-detail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--md) var(--wp--preset--spacing--2-xl);
  padding: 0 var(--page-x);
  font-size: var(--wp--preset--font-size--lg);
  line-height: normal;
}

.work-name {
  font-size: inherit;
  font-weight: 400;
}

.work-sub {
  display: flex;
  flex-wrap: wrap;
  gap: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--lg);
}

.live-preview {
  display: flex;
  align-items: center;
  gap: var(--wp--preset--spacing--xs);
  margin-left: auto;
  font-size: var(--wp--preset--font-size--sm);
  text-transform: uppercase;
}

.live-icon {
  width: 10px;
  height: 10px;
  background: var(--wp--preset--color--live);
  border-radius: 50%;
}

/* Blinks like an "on air" light to draw the eye (owner, 2026-10-30). */
@media (prefers-reduced-motion: no-preference) {
  .live-icon {
    animation: live-blink 1.4s ease-in-out infinite;
  }
}

@keyframes live-blink {
  50% { opacity: 0.15; }
}

.work-hero {
  display: flex;
  align-items: flex-end;
  gap: var(--wp--preset--spacing--lg);
  height: min(725px, 70vh); /* fits the first screen on a laptop, no dead band over a wide slide (critique, 2026-11-01) */
}

.work-hero-image {
  flex: none;
  width: 69.25%; /* 997 of 1440 */
  height: 100%;
}

/* contain, not cover: the whole image always shows, nothing is cropped. */
.work-hero-image .slide {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: left bottom;
}

.work-hero-caption {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--wp--preset--spacing--sm);
  min-width: 0;
  padding: 0 var(--wp--preset--spacing--lg) 0 var(--wp--preset--spacing--xs);
  font-size: var(--wp--preset--font-size--lg);
  line-height: normal;
}

.work-hero-caption hr {
  width: 100%;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--black);
}

.caption-nav {
  display: flex;
  align-items: center;
  gap: var(--wp--preset--spacing--sm);
  font-size: var(--wp--preset--font-size--sm);
}

.caption-nav .counter {
  margin-right: auto;
}

.caption-nav button {
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--black);
  border-radius: 50%;
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--wp--preset--font-size--lg);
  cursor: pointer;
}

.caption-nav button:hover {
  background: var(--black);
  color: var(--wp--preset--color--white);
}

/* Photo and graphic works: every image at once, uncropped, in columns (4 on a desktop, 2 on a
   phone), so nothing scrolls sideways (owner, 2026-10-28). */
.work-gallery {
  columns: 4 150px;
  column-gap: var(--wp--preset--spacing--md);
}

.work .work-gallery {
  padding: 0 var(--page-x);
}

.work-gallery--even {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 var(--wp--preset--spacing--md);
}

/* Editorial & Print Design: covers and menus are small pieces, so 5 columns on a desktop (owner,
   2026-10-31). The smaller screens below keep their 3 and 2. */
@media (min-width: 1101px) {
  .term-editorial .work-gallery {
    columns: 5 150px;
  }

  .term-editorial .work-gallery--even {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* Graphic Design filters: square buttons, the count in grey; the one showing is filled black. */
.folder-intro {
  max-width: 60ch;
  margin-bottom: var(--wp--preset--spacing--2-xl);
  font-size: var(--wp--preset--font-size--md);
}

/* After the work (Photography): space above instead of below. */
.folder-intro--after {
  margin: var(--wp--preset--spacing--2-xl) 0 0;
}

.folder-intro p + p {
  margin-top: var(--wp--preset--spacing--sm);
}

.work-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--wp--preset--spacing--xs);
  margin-bottom: var(--wp--preset--spacing--2-xl);
}

.work-filters a {
  display: inline-flex;
  align-items: baseline;
  gap: var(--wp--preset--spacing--xs);
  padding: 8px 14px;
  border: 1px solid var(--black);
  color: var(--black);
  text-decoration: none;
  line-height: normal;
}

.work-filters a span {
  font-size: var(--wp--preset--font-size--xs);
  color: var(--muted);
}

.work-filters a:hover {
  background: var(--wp--preset--color--paper);
}

.work-filters a[aria-current] {
  background: var(--black);
  color: var(--wp--preset--color--white);
}

.work-filters a[aria-current] span {
  color: #b3b3b3;
}

.work-gallery figure {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--xs);
  margin-bottom: var(--wp--preset--spacing--lg);
  break-inside: avoid;
  line-height: normal;
}

/* A note between the pieces: plain text, a size up from the captions (owner, 2026-10-28). */
.gallery-note {
  margin-bottom: var(--wp--preset--spacing--lg);
  font-size: var(--wp--preset--font-size--lg);
  line-height: 1.4;
  break-inside: avoid;
}

/* A note placed for one layout only (taxonomy-work_type.php): wide = desktop, narrow = tablet and phone,
   tablet, phone. */
@media (min-width: 1101px) {
  .gallery-note:is(.gallery-note--narrow, .gallery-note--tablet, .gallery-note--phone) {
    display: none;
  }
}

@media (min-width: 601px) {
  .gallery-note--phone {
    display: none;
  }
}

/* Tablet and down: three columns at most, and the note steps down a size, so a column of text stays
   readable (owner, 2026-10-30). */
@media (max-width: 1100px) {
  .work-gallery {
    columns: 3 150px;
  }

  .gallery-note--wide {
    display: none;
  }

  .gallery-note {
    font-size: var(--wp--preset--font-size--md);
  }
}

/* Phone: two columns, so a note's place is the same on every phone; a column is about 160px, so the note
   steps down once more to fit more words a line (owner, 2026-10-30); in a row grid (Video) it takes the
   full row. */
@media (max-width: 600px) {
  .work-gallery {
    columns: 2;
  }

  .gallery-note {
    font-size: var(--wp--preset--font-size--sm);
  }

  .gallery-note--tablet {
    display: none;
  }

  .work-gallery--even .gallery-note {
    grid-column: 1 / -1;
  }
}

.work-gallery a {
  display: block;
  cursor: zoom-in;
}

.work-gallery :is(img, video) {
  display: block;
  width: 100%;
  height: auto;
  outline: 1px solid rgb(0 0 0 / 0.08); /* a white logo or menu still shows its edge on the white page */
  outline-offset: -1px;
  transition: opacity 0.2s ease;
}

.work-gallery a:hover > img {
  opacity: 0.85;
}

/* Logo Design: the logo shows; while hovered or keyboard-focused it cycles mockup 1, mockup 2, then the
   logo again, and repeats (owner, 2026-10-28). Mockup 2 sits on top, so a crossfade never shows the logo. */
.work-gallery a:has(.gallery-hover) {
  position: relative;
}

.gallery-hover,
.gallery-hover img {
  position: absolute;
  inset: 0;
}

.gallery-hover > * {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .work-gallery a:is(:hover, :focus-visible) .gallery-hover img:nth-child(1) {
    animation: mockup-1 4.5s infinite;
  }

  .work-gallery a:is(:hover, :focus-visible) .gallery-hover img:nth-child(2) {
    animation: mockup-2 4.5s infinite;
  }

  .work-gallery a:is(:hover, :focus-visible) .gallery-tag {
    animation: mockup-tag 4.5s infinite;
  }

  /* Three mockups (METEOR): the same rhythm, one slot longer. */
  .work-gallery a:is(:hover, :focus-visible) .gallery-hover:has(> img:nth-child(3)) {
    & img:nth-child(1) { animation: mockup3-1 6s infinite; }
    & img:nth-child(2) { animation: mockup3-2 6s infinite; }
    & img:nth-child(3) { animation: mockup3-3 6s infinite; }
    & .gallery-tag { animation: mockup3-tag 6s infinite; }
  }
}

/* Phones and tablets have no hover, so there the mockups cycle by themselves (owner, 2026-11-01). Every
   other tile starts half a cycle in, so neighbouring logos do not fade in step. */
@media (hover: none) and (prefers-reduced-motion: no-preference) {
  .work-gallery .gallery-hover img:nth-child(1) {
    animation: mockup-1 4.5s infinite;
  }

  .work-gallery .gallery-hover img:nth-child(2) {
    animation: mockup-2 4.5s infinite;
  }

  .work-gallery .gallery-tag {
    animation: mockup-tag 4.5s infinite;
  }

  .work-gallery .gallery-hover:has(> img:nth-child(3)) {
    & img:nth-child(1) { animation: mockup3-1 6s infinite; }
    & img:nth-child(2) { animation: mockup3-2 6s infinite; }
    & img:nth-child(3) { animation: mockup3-3 6s infinite; }
    & .gallery-tag { animation: mockup3-tag 6s infinite; }
  }

  .work-gallery figure:nth-of-type(even) .gallery-hover > * {
    animation-delay: -2.25s;
  }
}

@keyframes mockup3-1 {
  0% { opacity: 0; }
  4%, 30% { opacity: 1; }
  31%, 100% { opacity: 0; }
}

@keyframes mockup3-2 {
  0%, 25% { opacity: 0; }
  30%, 55% { opacity: 1; }
  56%, 100% { opacity: 0; }
}

@keyframes mockup3-3 {
  0%, 50% { opacity: 0; }
  55%, 75% { opacity: 1; }
  80%, 100% { opacity: 0; }
}

@keyframes mockup3-tag {
  0% { opacity: 0; }
  4%, 75% { opacity: 1; }
  80%, 100% { opacity: 0; }
}

@keyframes mockup-1 {
  0% { opacity: 0; }
  5%, 40% { opacity: 1; }
  41%, 100% { opacity: 0; }
}

@keyframes mockup-2 {
  0%, 35% { opacity: 0; }
  40%, 70% { opacity: 1; }
  75%, 100% { opacity: 0; }
}

@keyframes mockup-tag {
  0% { opacity: 0; }
  5%, 70% { opacity: 1; }
  75%, 100% { opacity: 0; }
}

.gallery-tag {
  position: absolute;
  left: var(--wp--preset--spacing--xs);
  bottom: var(--wp--preset--spacing--xs);
  padding: 2px 6px;
  background: rgb(255 255 255 / 0.9);
  font-size: var(--wp--preset--font-size--xs);
}

/* Reduced motion: no cycling, hover just shows the first mockup. */
@media (prefers-reduced-motion: reduce) {
  .work-gallery a:is(:hover, :focus-visible) .gallery-hover :is(img:first-child, .gallery-tag) {
    opacity: 1;
  }
}

/* A printed piece with several pages (owner, 2026-10-31): the other pages sit on the cover, at its size,
   and main.js shows them one by one on hover. The corner count says there is more than one page. */
.work-gallery a[data-pages] {
  position: relative;
  display: block;
}

.gallery-pages img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
}

.gallery-pages img.is-on {
  opacity: 1;
}

.gallery-count {
  position: absolute;
  right: var(--wp--preset--spacing--xs);
  bottom: var(--wp--preset--spacing--xs);
  padding: 2px 8px;
  border: 1px solid var(--black); /* square and black like the active filter button (owner, 2026-10-31) */
  background: var(--black);
  color: var(--wp--preset--color--white);
  font-size: var(--wp--preset--font-size--xs);
  line-height: normal;
}

/* Video: a small play mark in the corner says "click for the full video with sound". */
.work-gallery a[data-video] {
  position: relative;
}

.video-badge {
  position: absolute;
  right: var(--wp--preset--spacing--xs);
  bottom: var(--wp--preset--spacing--xs);
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.6);
  color: #fff;
  font-size: 11px;
  padding-left: 2px;
}

.work-gallery .placeholder {
  aspect-ratio: 4 / 5;
}

.work-gallery figcaption {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.gallery-name {
  font-size: var(--wp--preset--font-size--sm);
}

.gallery-desc,
.lightbox-meta {
  font-size: var(--wp--preset--font-size--xs);
  color: var(--muted);
}

/* Full-screen viewer: one image at a time on near-black, whole and as large as fits. */
.lightbox {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: var(--wp--preset--spacing--md);
  border: 0;
  background: rgb(0 0 0 / 0.94);
  color: var(--wp--preset--color--white);
}

.lightbox[open] {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
}

.lightbox:focus {
  outline: none; /* focused on open by a tap (main.js); a ring round the whole screen says nothing */
}

.lightbox::backdrop {
  background: transparent;
}

body:has(.lightbox[open]) {
  overflow: hidden;
}

.lightbox figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--wp--preset--spacing--sm);
  text-align: center;
}

.lightbox :is(img, video) {
  max-width: 100%;
  max-height: calc(100dvh - 140px);
  object-fit: contain;
}

.lightbox .lightbox-meta {
  color: #b3b3b3;
}

.lightbox button {
  min-width: 64px; /* the arrow column is then wider than the close button above it, so a wide image never reaches under the X */
  padding: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--sm);
  border: 0;
  background: none;
  color: inherit;
  font-size: 40px;
  line-height: 1;
  cursor: pointer;
}

.lightbox button:focus-visible {
  outline: 2px solid var(--wp--preset--color--white);
}

.lightbox-close {
  position: absolute;
  top: var(--wp--preset--spacing--sm);
  right: var(--wp--preset--spacing--sm);
}

.work-notes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--wp--preset--spacing--2-xl);
  padding: var(--wp--preset--spacing--2-xl) var(--page-x) var(--wp--preset--spacing--4-xl);
}

.work-facts {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--md);
}

.work-facts dt {
  font-size: var(--wp--preset--font-size--xs);
  color: var(--muted);
}

.work-facts dd {
  margin: 0;
}

.work-content {
  max-width: 65ch;
}

.work-content > * + * {
  margin-top: 1em;
}

.work-content h2 {
  font-size: var(--wp--preset--font-size--lg);
  font-weight: 600;
}

.work-content h2:not(:first-child) {
  margin-top: 2em;
}

.work-content ul {
  padding-left: 1.25em;
  list-style: disc;
}

/* 7 Text page (Figma 80:497) --------------------------------------------------------------------- */

.text-page {
  max-width: calc(var(--wp--style--global--content-size) + 2 * var(--page-x));
  padding: var(--wp--preset--spacing--2-xl) var(--page-x) var(--wp--preset--spacing--4-xl);
}

.headline {
  margin-bottom: var(--wp--preset--spacing--2-xl);
  font-size: var(--wp--preset--font-size--xl);
  font-weight: 400;
  line-height: 1.2;
}

.text-body {
  max-width: 65ch;
}

.text-body > * + * {
  margin-top: 1em;
}

.text-body h2 {
  margin-top: var(--wp--preset--spacing--2-xl);
  font-size: var(--wp--preset--font-size--sm);
  font-weight: 400;
}

/* The closing thank-you (README.md): a section's worth of space above it, as a heading gets. */
.text-body .text-signoff {
  margin-top: var(--wp--preset--spacing--2-xl);
}

/* Resume sections (owner, 2026-11-01): a thin line over each, a heading that stands out from the text,
   then two-column rows, what on the left and when on the right; stacked on a phone. */
.text-body .resume-section {
  margin-top: var(--wp--preset--spacing--2-xl);
  padding-top: var(--wp--preset--spacing--md);
  border-top: 1px solid var(--black);
}

.resume-section h2 {
  margin: 0 0 var(--wp--preset--spacing--sm);
  font-size: var(--wp--preset--font-size--md);
  font-weight: 400; /* not heavier than the page title (critique, 2026-11-01) */
}

/* Canada and Thailand under Experience: a small grey label, like the dates. */
.resume-group {
  margin: var(--wp--preset--spacing--md) 0 4px;
  color: var(--muted);
  font-size: var(--wp--preset--font-size--sm);
  font-weight: 400;
}

.resume-section h2 + .resume-group {
  margin-top: 0;
}

/* "Resume" over the name on the Resume page (owner, 2026-11-01). */
.headline-label {
  margin-bottom: var(--wp--preset--spacing--xs);
  color: var(--muted);
}

.resume-rows li,
.resume-skills div {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px var(--wp--preset--spacing--md);
  padding: 6px 0;
}

.resume-skills div {
  grid-template-columns: 9rem 1fr;
}

.resume-when,
.resume-skills dt {
  color: var(--muted);
}

.resume-when {
  white-space: nowrap;
}

.resume-skills dd {
  margin: 0;
}

.resume-more {
  margin-top: var(--wp--preset--spacing--xs);
}

.resume-more a {
  text-decoration: underline;
}

@media (max-width: 600px) {
  .resume-rows li,
  .resume-skills div {
    grid-template-columns: 1fr;
  }
}

/* Resume download (inc/resume-request.php). */
.resume-request {
  margin-top: var(--wp--preset--spacing--3-xl);
  padding-top: var(--wp--preset--spacing--2-xl);
  border-top: 1px solid var(--black);
}

/* The PDFs, one plain line each (owner, 2026-11-01): the document icon, then the name underlined. */
.resume-files {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The icon keeps its own column, so a name that wraps on a phone stays beside it. */
.resume-file {
  display: inline-grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 8px;
  color: var(--black);
  text-decoration: none;
}

.resume-file .crumb-icon {
  display: block; /* shown on phones too, where the breadcrumb hides its icons */
  width: 13px;
  height: 16px;
  padding: 0;
}

.resume-file-name {
  text-decoration: underline;
  overflow-wrap: anywhere;
}

.resume-file:hover .resume-file-name {
  text-decoration: none;
}

/* At the top of the Resume page there is nothing above it to divide from (owner, 2026-11-01). */
.resume-request:first-child {
  margin: 0 0 var(--wp--preset--spacing--2-xl);
  padding-top: 0;
  border-top: 0;
}

/* 8 Placeholders --------------------------------------------------------------------------------- */

.placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-height: 120px;
  padding: var(--wp--preset--spacing--sm);
  background: var(--grey);
  color: var(--muted);
  font-size: var(--wp--preset--font-size--xs);
  text-align: center;
}

/* 9 Small screens -------------------------------------------------------------------------------- */

@media (max-width: 1100px) {
  .site-header {
    flex-wrap: wrap;
    padding-block: var(--wp--preset--spacing--2-xl);
  }

  .tagline {
    order: 4;
    width: 100%;
  }

  .work-grid {
    gap: var(--wp--preset--spacing--2-xl);
  }

  .work-hero {
    flex-direction: column;
    align-items: stretch;
    height: auto;
  }

  .work-hero-image {
    width: 100%;
    height: auto;
    aspect-ratio: 997 / 725;
  }

  .work-hero-caption {
    padding: 0 var(--page-x);
  }
}

@media (max-width: 820px) {
  .folder-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--wp--preset--spacing--2-xl) var(--wp--preset--spacing--md);
  }

  .folders {
    padding-top: var(--wp--preset--spacing--2-xl);
  }

  .folder-label {
    font-size: var(--wp--preset--font-size--sm);
    text-align: center;
  }

  .icon-folder {
    width: 100%;
    max-width: 230px;
  }

  .icon-doc {
    width: 62%;
    max-width: 150px;
  }

  .work-notes {
    grid-template-columns: 1fr;
  }

  .work-gallery--even {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* On a phone the arrows sit under the image, so it gets the whole width. The close button gets a
     row of its own above it: in the corner it covered a full-width image (owner, 2026-11-01). */
  .lightbox[open] {
    grid-template-columns: 1fr 1fr;
    align-content: center;
  }

  .lightbox-close {
    position: static;
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  .lightbox figure {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  .lightbox :is(img, video) {
    max-height: calc(100dvh - 260px); /* room for the close row, the caption and the arrows */
  }

  .lightbox [data-prev] {
    grid-row: 3;
    justify-self: start;
  }

  .lightbox [data-next] {
    grid-row: 3;
    justify-self: end;
  }
}

@media (max-width: 600px) {
  /* The breadcrumb on one short line, text only, so the work starts higher (critique, 2026-11-01). A long
     last step is cut with an ellipsis. */
  .crumbs {
    padding-block: var(--wp--preset--spacing--md);
  }

  .crumbs ol {
    flex-wrap: nowrap;
  }

  .crumbs ol,
  .crumbs li,
  .crumb {
    gap: var(--wp--preset--spacing--xs);
  }

  .crumbs li:last-child {
    min-width: 0;
  }

  .crumb-icon {
    display: none;
  }

  .crumb-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Year, tagline and role as one grey line under the title. */
  .work-sub {
    display: block;
    color: var(--muted);
    font-size: var(--wp--preset--font-size--sm);
  }

  .work-sub span + span::before {
    content: " \00b7  "; /* a middle dot: the tagline can end in a full stop, so a comma would double up */
  }

  /* Tighter gaps keep the mark and three nav items on one row at 375px (Resume joined the nav, 2026-11-01). */
  .site-header {
    column-gap: var(--wp--preset--spacing--sm);
  }

  .site-nav {
    order: 2;
  }

  .site-nav ul {
    gap: var(--wp--preset--spacing--sm);
  }

  .work-grid {
    grid-template-columns: 1fr;
  }

  .site-footer {
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
  }

  .live-preview {
    margin-left: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}

/* 10 Experience (Figma 58:1416) ------------------------------------------------------------------ */

.experience {
  display: grid;
  grid-template-columns: minmax(0, 420px) minmax(0, 640px);
  justify-content: space-between;
  align-items: start;
  gap: var(--wp--preset--spacing--2-xl);
  padding: var(--wp--preset--spacing--4-xl) var(--page-x);
}

.experience-list {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--2-xl);
}

.experience-year-title {
  margin-bottom: var(--wp--preset--spacing--md);
  font-size: 24px;
  font-weight: 400;
  line-height: normal;
}

.experience-year ul {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--md);
}

.experience-row {
  display: flex;
  align-items: center;
  gap: var(--wp--preset--spacing--sm);
  min-height: 34px;
  font-size: var(--wp--preset--font-size--lg);
  line-height: 1.25;
}

/* The open row is black, the rest grey (owner, 2026-10-30), so hover turns a grey row black instead of
   the site's usual black-to-grey. The logos are black images, so opacity gives the same grey.
   The grey rows are 30% lighter than --muted (owner, 2026-11-01). */
.experience-row {
  color: #767676; /* the lightest grey that still passes WCAG AA, 4.5:1 (critique, 2026-11-01; was #8b8b8b) */
}

.experience-row .experience-logo {
  opacity: 0.54; /* black at 54% is about #767676, the same as the row text */
  transition: opacity 0.2s ease;
}

.experience-row:hover,
.experience-row[aria-current="true"] {
  color: var(--black);
  text-decoration: none;
}

.experience-row:hover .experience-logo,
.experience-row[aria-current="true"] .experience-logo {
  opacity: 1;
}

.experience-row-role {
  display: block;
}

.experience-row-place {
  display: block;
  margin-top: 2px;
  font-size: var(--wp--preset--font-size--sm);
}

.experience-row-tag {
  display: inline-block;
  margin-left: var(--wp--preset--spacing--xs);
  vertical-align: 0.15em;
  padding: 2px 6px;
  border: 1px solid currentColor;
  color: var(--muted);
  font-size: var(--wp--preset--font-size--xs);
  line-height: 1.2;
}

/* The company's logo, all black, small; wide wordmarks get a little more room than square marks. An
   empty box keeps the names lined up when there is no logo yet. */
.experience-logo {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 24px;
}

.experience-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* The panel stays pinned at the top while the list scrolls, at its full height with no scroll of its own
   (owner, 2026-10-30). Near the end of the list it is pushed up with it; main.js brings its top back. */
.experience-detail {
  position: sticky;
  top: var(--wp--preset--spacing--md);
}

.experience-panel {
  --panel-gap: var(--wp--preset--spacing--3-xl);
  display: flex;
  flex-direction: column;
  gap: var(--panel-gap);
  padding: 41px var(--wp--preset--spacing--3-xl);
  font-size: var(--wp--preset--font-size--lg);
  line-height: 1.4;
}

/* The gap under the logo is 20% smaller than the panel's other gaps (owner, 2026-10-31). */
.experience-panel-head {
  margin-bottom: calc(var(--panel-gap) * -0.2);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--wp--preset--spacing--md);
}

.experience-panel-logo {
  width: auto;
  max-width: 160px;
  height: 48px;
  object-fit: contain;
  object-position: left center;
}

.experience-name {
  font-size: 24px;
  font-weight: 400;
  line-height: normal;
}

.detail-block {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--md);
  max-width: 512px;
}

.detail-block h3 {
  font-size: inherit;
  font-weight: 400;
}

.detail-block p + p {
  margin-top: calc(-1 * var(--wp--preset--spacing--sm));
}

/* Folders and covers in the panel: the Home folder, filling a third of the panel. */
.panel-folders {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--wp--preset--spacing--md);
  padding-top: var(--wp--preset--spacing--sm); /* room for the cover when it rises on hover */
}

.panel-folders .icon-folder {
  width: 100%;
}

.panel-folders .folder-label {
  font-size: var(--wp--preset--font-size--sm);
}

.panel-links {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--xs);
}

.experience-panel .work-gallery {
  columns: 3 120px;
}

.text-meta {
  margin: calc(-1 * var(--wp--preset--spacing--md)) 0 var(--wp--preset--spacing--2-xl);
  color: var(--muted);
}

@media (max-width: 900px) {
  .experience {
    grid-template-columns: 1fr;
    padding-top: var(--wp--preset--spacing--2-xl);
  }

  .experience-detail {
    position: static;
    scroll-margin-top: var(--wp--preset--spacing--md);
  }

  .experience-panel {
    padding: var(--wp--preset--spacing--2-xl) 0 0;
    border-top: 1px solid var(--black);
    --panel-gap: var(--wp--preset--spacing--2-xl);
  }

  .experience-row {
    font-size: var(--wp--preset--font-size--sm);
  }

  .experience-row-place {
    font-size: var(--wp--preset--font-size--xs);
  }
}

