/* ---------------------------------------------------------
   Candice Lam — portfolio, editorial edition
   Light mode only. Four pages, each exactly one viewport:
   nothing scrolls, in either direction.
--------------------------------------------------------- */

:root {
  /* surfaces */
  --bg:            #F7F6F2;   /* warm paper */
  --surface:       #FFFFFF;
  --surface-sunk:  #EFEDE7;
  --line:          rgba(25, 25, 23, 0.08);
  --line-strong:   rgba(25, 25, 23, 0.16);

  /* ink */
  --ink:           #191917;
  --ink-2:         #55544E;
  --ink-3:         #8C8A81;

  /* accents */
  --a-blush:       #F3D9CE;
  --a-clay:        #E4B9A4;
  --a-sage:        #CBD8C6;
  --a-sky:         #C9D6E6;
  --a-butter:      #F0E3C2;

  /* type */
  --serif: "Playfair Display", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --sans:  "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  /* system */
  --pad:     clamp(20px, 2.8vw, 40px);  /* page gutter */
  --col-gap: clamp(16px, 2vw, 32px);
  --radius:  18px;
  --shadow:      0 1px 2px rgba(25,25,23,.04), 0 8px 24px rgba(25,25,23,.06);
  --shadow-lift: 0 2px 4px rgba(25,25,23,.05), 0 18px 40px rgba(25,25,23,.09);
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
}

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

/* the whole site is one viewport: the document itself never scrolls */
html, body {
  height: 100%;
  overflow: hidden;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* paper grain over everything */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 100;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.16'/%3E%3C/svg%3E");
}

a { color: inherit; text-decoration: none; }
p, h1, h2, dl, dd, ol, ul, figure { margin: 0; }
ol, ul { padding: 0; list-style: none; }

::selection { background: var(--a-clay); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--bg);
  border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; }

/* placeholder copy still to be confirmed: delete the class once real */
.edit { box-shadow: inset 0 -0.55em 0 rgba(228, 185, 164, .32); }

/* inline text links */
.note p a,
.links a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 3px;
  transition: text-decoration-color .3s var(--ease), color .3s var(--ease);
}
.note p a:hover,
.links a:hover { text-decoration-color: var(--ink); color: var(--ink); }

/* ---------------------------------------------------------
   App frame: stage / dock / footer, exactly 100dvh tall
--------------------------------------------------------- */

.app {
  position: relative;
  z-index: 1;
  height: 100vh;
  height: 100dvh;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  padding: 0 var(--pad);
  padding-left:  max(var(--pad), env(safe-area-inset-left));
  padding-right: max(var(--pad), env(safe-area-inset-right));
  /* one compositing layer for all the content: with the scene's moving
     layers underneath, Safari would otherwise split overlapping text into
     many small layers of its own */
  will-change: transform;
}

.stage {
  position: relative;
  min-height: 0;
}

/* ---------------------------------------------------------
   Pages — stacked in the stage, one visible at a time
--------------------------------------------------------- */

.page {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  padding-top: var(--pad);
  overflow: hidden;

  opacity: 0;
  visibility: hidden;
  transition: opacity .3s var(--ease), visibility 0s linear .3s;
}

.page.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity .45s var(--ease) .12s, visibility 0s;
}

.page__body {
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--col-gap);
  padding-bottom: clamp(12px, 2.5vh, 28px);
}

/* staggered entrance for the blocks inside a page */
.rise {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .5s var(--ease), transform .6s var(--ease);
}

.page.is-active .rise {
  opacity: 1;
  transform: none;
  transition: opacity .8s var(--ease-out), transform 1s var(--ease-out);
  transition-delay: calc(.32s + var(--i, 0) * .08s);
}

/* ---------------------------------------------------------
   Display titles — big serif, revealed from behind a mask
--------------------------------------------------------- */

.display {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(46px, min(9vw, 15vh), 168px);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  outline: none;
}

.display em { font-style: italic; letter-spacing: -0.035em; }

.display__mask {
  display: block;
  overflow: hidden;
  padding: .02em .06em .14em 0;   /* room for the italic's overhang */
  margin-bottom: -.14em;
}

.display__text {
  display: block;
  transform: translateY(102%);
  transition: transform .6s var(--ease);
}

/* her signature candy beside the name on Home; rises with it */
.display__candy {
  display: inline-block;
  width: .62em;
  height: .62em;
  margin-left: .24em;
  vertical-align: .02em;
  overflow: visible;
}
.nowrap { white-space: nowrap; }

.page.is-active .display__text {
  transform: none;
  transition: transform 1.05s var(--ease-out) .18s;
}

/* ---------------------------------------------------------
   Notes — small label over a hairline, then copy
--------------------------------------------------------- */

.note__label {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: 12px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--line-strong);
}

.note p {
  color: var(--ink-2);
  max-width: 48ch;
}

.note p + p { margin-top: .9em; }

.lede {
  font-family: var(--serif);
  font-size: clamp(19px, 1.45vw, 24px);
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--ink) !important;
}

/* key/value pairs */
.pairs { display: flex; flex-direction: column; gap: 10px; }
.pairs > div {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 14px;
  align-items: baseline;
}
.pairs dt { color: var(--ink-3); font-size: 13.5px; }
.pairs dd { color: var(--ink); font-family: var(--serif); font-size: 17px; line-height: 1.3; }

.pairs--stacked { gap: 14px; }
.pairs--stacked dd { font-size: 18px; }

/* ---------------------------------------------------------
   HOME — scattered notes, after the reference
--------------------------------------------------------- */

.home {
  grid-template-rows: auto minmax(0, 1fr) auto;
  row-gap: clamp(16px, 3vh, 32px);
}

.note--intro {
  grid-column: 1 / span 4;
  grid-row: 1;
  margin-top: clamp(20px, 5vh, 56px);
}

/* --- Selected work: crayon icons of each project --- */

.shelf {
  grid-column: 6 / -1;
  grid-row: 2;
  align-self: center;
  position: relative;
  z-index: 2;              /* previews pop over the notes */
}

.shelf__row {
  display: flex;
  justify-content: space-between;
  gap: clamp(12px, 2vw, 28px);
  padding-top: 4px;
}

.doodle {
  position: relative;
  flex: 1;
  max-width: 190px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
  outline: none;
}

.doodle__icon {
  width: clamp(64px, min(7vw, 12vh), 112px);
  height: auto;
  aspect-ratio: 1;
  overflow: visible;
  margin-bottom: 8px;
  transition: transform .45s var(--ease-out);
}
/* a little scrapbook wiggle on hover */
.doodle:hover .doodle__icon,
.doodle:focus-visible .doodle__icon { transform: rotate(-6deg) scale(1.08); }
.doodle:nth-child(even):hover .doodle__icon,
.doodle:nth-child(even):focus-visible .doodle__icon { transform: rotate(5deg) scale(1.08); }
.doodle:focus-visible .doodle__title { text-decoration: underline; text-underline-offset: 3px; }

.doodle__title { font-family: var(--serif); font-size: clamp(16px, 1.3vw, 19px); line-height: 1.2; color: var(--ink); white-space: nowrap; }
.doodle__meta  { font-size: 11.5px; letter-spacing: .02em; color: var(--ink-3); }

/* the preview card that pops above an icon on hover */
.peek {
  --x: -50%;
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  width: clamp(200px, 17vw, 240px);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 10px 12px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  box-shadow: var(--shadow-lift);
  opacity: 0;
  visibility: hidden;
  transform: translate(var(--x), 10px) rotate(-1.5deg) scale(.96);
  transform-origin: 50% 100%;
  transition: opacity .2s var(--ease), transform .35s var(--ease-out), visibility 0s linear .35s;
  pointer-events: none;
}
.doodle:first-child .peek { --x: 0%; left: 0; transform-origin: 20% 100%; }
.doodle:last-child .peek  { --x: 0%; left: auto; right: 0; transform-origin: 80% 100%; }
.doodle:hover .peek,
.doodle:focus-visible .peek {
  opacity: 1;
  visibility: visible;
  transform: translate(var(--x), 0) rotate(-1.5deg);
  transition: opacity .2s var(--ease), transform .35s var(--ease-out), visibility 0s;
}

.peek__frame {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 9px;
  background: var(--surface-sunk);
  margin-bottom: 6px;
}
.peek__frame .art { position: absolute; inset: 0; }
.peek__frame .art__tile { width: 28px; height: 28px; }
.peek__title { font-family: var(--serif); font-size: 17px; line-height: 1.2; color: var(--ink); }
.peek__meta  { font-size: 11.5px; color: var(--ink-3); }

/* touch screens can't hover: a tap goes straight to the project */
@media (hover: none) {
  .peek { display: none; }
}

.note--currently {
  grid-column: 1 / span 3;
  grid-row: 3;
  align-self: end;
}

/* ---------------------------------------------------------
   ABOUT
--------------------------------------------------------- */

.about {
  grid-template-rows: minmax(0, 1fr);
  padding-top: clamp(20px, 5vh, 56px);
}

.about__copy  { grid-column: 1 / span 4; align-self: start; }
.about__facts { grid-column: 5 / span 4; align-self: end; }

.portrait {
  position: relative;
  grid-column: 9 / -1;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}

/* her signature candy, stuck on the photo's corner like a sticker */
.portrait__candy {
  position: absolute;
  top: calc(clamp(44px, 4.4vw, 64px) * -0.36);
  left: calc(clamp(44px, 4.4vw, 64px) * -0.36);
  z-index: 2;
  width: clamp(44px, 4.4vw, 64px);
  height: auto;
  aspect-ratio: 1;
  overflow: visible;
  transform: rotate(-6deg);
  filter: drop-shadow(0 2px 3px rgba(25, 25, 23, .14));
  pointer-events: none;
}

.portrait__frame {
  position: relative;
  flex: 1;
  min-height: 0;
  max-height: 560px;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(160deg, #FBF1EB 0%, #F1DED3 55%, #E9D2C4 100%);
}

/* the portrait can't be dragged out, long-pressed or right-clicked to save:
   a clear layer sits on top so the image itself never gets the click, and
   script.js turns off the right-click menu here */
[data-protect] {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
[data-protect]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
[data-protect] img { pointer-events: none; -webkit-user-drag: none; }

/* the photo fills whatever shape the frame takes (tall on desktop, a wide
   banner on short tablets), anchored on her face so it never crops out */
.portrait__frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 55% 24%;
}

.portrait__caption,
.preview__caption {
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--ink-3);
}

/* ---------------------------------------------------------
   WORK — index on the left, live preview on the right
--------------------------------------------------------- */

.work {
  grid-template-rows: minmax(0, 1fr);
  padding-top: clamp(20px, 5vh, 56px);
}

.index {
  grid-column: 1 / span 6;
  align-self: end;
  border-bottom: 1px solid var(--line-strong);
}

.index__row {
  /* a <button>: it drives the preview, it doesn't navigate */
  width: 100%;
  margin: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: default;
  display: grid;
  grid-template-columns: 3.2em 1fr auto;
  align-items: baseline;
  gap: 12px;
  padding: clamp(10px, 1.9vh, 20px) 0;
  border-top: 1px solid var(--line-strong);
  color: var(--ink-3);
  transition: color .35s var(--ease), padding-left .45s var(--ease);
}

.index__num {
  font-family: var(--serif);
  font-style: italic;
  font-size: 18px;
}

.index__title {
  font-family: var(--serif);
  font-size: clamp(26px, min(3vw, 5.2vh), 46px);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.index__meta {
  font-size: 12.5px;
  letter-spacing: .01em;
  white-space: nowrap;
}

.index__row.is-current {
  color: var(--ink);
  padding-left: 10px;
}

.preview {
  grid-column: 8 / -1;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}

.preview__frame {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface-sunk);
  box-shadow: var(--shadow);
}

.preview__frame .art {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(1.04);
  transition: opacity .6s var(--ease), transform 1.1s var(--ease-out);
}

.preview__frame .art.is-shown {
  opacity: 1;
  transform: none;
}

.preview__caption {
  flex: none;
  display: flex;
  gap: 14px;
  align-items: baseline;
}

/* all descriptions / labels share one grid cell (see setProject) */
.is-stacked { display: inline-grid; }
.is-stacked > span { grid-area: 1 / 1; visibility: hidden; }
.is-stacked > .is-on { visibility: visible; }

.preview__num {
  font-family: var(--serif);
  font-style: italic;
  font-size: 15px;
  color: var(--ink);
}

.preview__desc { max-width: 52ch; }

/* projects that open (data-open on their row) get a clickable preview */
.preview__open {
  display: none;
  flex: none;
  order: 3;
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 3px;
}
.preview__open:hover { text-decoration-color: var(--ink); }
/* the stacked label is its own box, so the underline has to be set on it;
   labels align right so the shorter ones still sit against the arrow */
.preview__cta.is-stacked { justify-items: end; }
.preview__cta.is-stacked > span {
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 3px;
}
.preview__open:hover .preview__cta > span { text-decoration-color: var(--ink); }
.preview.can-open .preview__open { display: inline; }
.preview.can-open .preview__frame { cursor: pointer; }
.index__row[data-open] { cursor: pointer; }

/* the Japan guide preview: Fuji, a red sun, a soft sky */
.art--japan { background: linear-gradient(180deg, #F6EDE4 0%, #F3E6DA 55%, #ECEADF 100%); }
.japan-art {
  position: absolute;
  left: 50%;
  top: 52%;
  height: 76%;
  width: auto;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  overflow: visible;
}

/* the agenda preview: three of its pages, fanned, on its own tan */
.art--prospectus { background: linear-gradient(160deg, #EFE7DD, #E2D6C8); }
.art--prospectus .fan { aspect-ratio: 906 / 1400; }

/* the lookbook preview: three of its pages, fanned */
.art--kitsune { background: linear-gradient(160deg, #EFEDE6, #E4E2D6); }
.fan {
  position: absolute;
  top: 50%;
  left: 50%;
  height: 74%;
  width: auto;
  aspect-ratio: 978 / 1400;
  border-radius: 3px;
  box-shadow: 0 2px 6px rgba(25,25,23,.12), 0 14px 30px rgba(25,25,23,.14);
  transition: transform .7s var(--ease-out);
}
.fan--back  { transform: translate(-82%, -50%) rotate(-7deg); }
.fan--mid   { transform: translate(-18%, -52%) rotate(6deg); }
.fan--front { transform: translate(-50%, -48%) rotate(-1.5deg); }
.preview.can-open .preview__frame:hover .fan--back  { transform: translate(-90%, -50%) rotate(-9deg); }
.preview.can-open .preview__frame:hover .fan--mid   { transform: translate(-10%, -52%) rotate(8deg); }

/* ---------------------------------------------------------
   CONTACT
--------------------------------------------------------- */

.contact {
  grid-template-rows: minmax(0, 1fr) auto;
  row-gap: clamp(18px, 3.5vh, 36px);
  padding-top: clamp(18px, 4vh, 44px);
}

/* frameless crayon doodles above the email: a paper plane loops past and
   the envelope sends up hearts. script.js moves them (only while Contact
   is showing); these positions are the still frame for reduced motion */
.contact__doodles {
  grid-column: 1 / -1;
  position: relative;
  min-height: 0;
  opacity: .85;
  pointer-events: none;
}

.contact__doodles svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cd-plane, .cd-dot, .cd-env, .cd-heart, .cd-star {
  position: absolute;
  will-change: transform;
}

.cd-plane {
  left: 30%;
  top: 22%;
  width: clamp(56px, 7vw, 108px);
  aspect-ratio: 100 / 60;
  transform: rotate(-8deg);
}

/* the dotted trail behind the plane */
.cd-dot {
  left: 0;
  top: 0;
  width: clamp(8px, .9vw, 13px);
  aspect-ratio: 1;
  opacity: 0;
  will-change: transform, opacity;
}
.cd-dot circle { fill: #ADA0D8; }

.cd-env {
  right: 12%;
  bottom: 4%;
  width: clamp(84px, 11vw, 168px);
  aspect-ratio: 120 / 90;
}
.cd-env__body { position: relative; }

/* hearts start tucked behind the letter and float up out of it */
.cd-heart {
  left: 36%;
  top: 8%;
  width: 28%;
  aspect-ratio: 40 / 36;
  will-change: transform, opacity;
}
.cd-heart--1 { transform: translate(-30%, -150%) rotate(-10deg); }
.cd-heart--2 { opacity: 0; }

.cd-star {
  width: clamp(13px, 1.5vw, 20px);
  aspect-ratio: 1;
  color: #E2B24A;
}
.cd-star svg { stroke: currentColor; stroke-width: 2; }
.cd-star--1 { left: 7%;  top: 18%; }
.cd-star--2 { left: 52%; top: 8%;  width: clamp(10px, 1.1vw, 15px); }
.cd-star--3 { left: 64%; top: 70%; width: clamp(11px, 1.2vw, 16px); }
.cd-star--4 { left: 94%; top: 26%; width: clamp(10px, 1vw, 14px); }

.contact__doodles .boil-1,
.contact__doodles .boil-2 { position: absolute; inset: 0; opacity: 0; }

.contact__note {
  grid-column: 7 / -1;
  align-self: end;
}

/* the invitation reads as a big serif line, like the ledes elsewhere */
.contact__note p {
  font-family: var(--serif);
  font-size: clamp(22px, min(2.3vw, 4.2vh), 36px);
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: 24ch;
}

.links {
  display: flex;
  gap: 28px;
  margin-top: clamp(16px, 2.6vh, 26px);
  font-size: 16px;
  font-weight: 500;
}
.links a { color: var(--ink); }
.links a span { display: inline-block; margin-left: .3em; transition: transform .35s var(--ease); }
.links a:hover span { transform: translateX(3px); }
.links a[target="_blank"]:hover span { transform: translate(2px, -2px); }

/* ---------------------------------------------------------
   Footer — one row:  © ——————— [ dock ] ——————— clock
   The rule runs in from both sides and the dock sits on it.
   The sides are equal 1fr columns, so the dock is dead centre
   whatever the widths of the copyright and the clock.
--------------------------------------------------------- */

.footer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  column-gap: 18px;
  padding: clamp(10px, 1.8vh, 18px) 0;
  padding-bottom: max(clamp(12px, 2vh, 20px), env(safe-area-inset-bottom));
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--ink-3);
}

.footer__side {
  display: flex;
  align-items: center;
  gap: 18px;
  min-width: 0;
}

.footer__copy { white-space: nowrap; }

.footer__rule {
  flex: 1;
  min-width: 16px;
  height: 1px;
  background: var(--line-strong);
}

.clock { display: flex; gap: 10px; align-items: baseline; white-space: nowrap; }

.clock__time {
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  min-width: 8.6em;          /* holds its width while the seconds tick */
  text-align: right;
}
/* one equal box per digit (see boxDigits in script.js) */
.clock__d {
  display: inline-block;
  width: .63em;
  text-align: center;
}

/* --- the dock: a segmented control with a sliding pill --- */

.dock__track {
  position: relative;
  display: flex;
  gap: 2px;
  padding: 4px;
  border-radius: 13px;
  border: 1px solid var(--line-strong);
  background: rgba(255, 255, 255, .78);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
          backdrop-filter: blur(12px) saturate(1.2);
  box-shadow: var(--shadow);
}

.dock__pill {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: 0;
  border-radius: 9px;
  background: var(--ink);
  box-shadow: 0 2px 8px rgba(25, 25, 23, .18);
}

.dock.is-ready .dock__pill {
  transition: transform .55s var(--ease-out), width .55s var(--ease-out);
}

.dock__link {
  position: relative;
  z-index: 1;
  min-width: 82px;
  padding: 8px 18px;
  border-radius: 9px;
  text-align: center;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--ink-3);
  transition: color .35s var(--ease);
}

.dock__link:hover { color: var(--ink); }
.dock__link[aria-current="page"] { color: var(--bg); }

/* ---------------------------------------------------------
   Project viewer — the lookbook, full screen, no scrolling.
   Desktop shows two-page spreads like the printed book; narrow
   screens show one page at a time.
--------------------------------------------------------- */

.viewer {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: minmax(200px, 290px) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  column-gap: clamp(20px, 3vw, 48px);
  row-gap: clamp(10px, 2vh, 20px);
  padding: var(--pad);
  padding-bottom: max(var(--pad), env(safe-area-inset-bottom));
  background: var(--bg);
  animation: viewer-in .35s var(--ease-out);
}
.viewer[hidden] { display: none; }
@keyframes viewer-in { from { opacity: 0; } }

.viewer__head {
  grid-column: 1 / -1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.viewer__kicker {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 8px;
}

.viewer__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(30px, min(4vw, 6.5vh), 60px);
  line-height: 1;
  letter-spacing: -0.02em;
}
.viewer__title em { font-style: italic; color: var(--ink-2); }

.viewer__close {
  flex: none;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

/* close and page arrows: a crayon ring and glyph (see #crayon-ui);
   hovering fills the ring in, like the solid buttons they replaced */
.crayon-btn {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.crayon-btn__ring {
  fill: var(--surface);
  stroke: #ABA492;
  stroke-width: 1.9;
  transition: fill .3s var(--ease), stroke .3s var(--ease);
}
.crayon-btn__glyph {
  stroke: var(--ink);
  stroke-width: 2.5;
  transition: stroke .3s var(--ease);
}
:is(.viewer__close, .viewer__step:not(:disabled)):hover .crayon-btn__ring { fill: var(--ink); stroke: var(--ink); }
:is(.viewer__close, .viewer__step:not(:disabled)):hover .crayon-btn__glyph { stroke: var(--bg); }

.viewer__about {
  grid-column: 1;
  grid-row: 2;
  align-self: end;
  display: flex;
  flex-direction: column;
  gap: 12px;
  color: var(--ink-2);
  font-size: 14px;
}
.viewer__lede {
  font-family: var(--serif);
  font-size: clamp(18px, 1.4vw, 21px);
  line-height: 1.35;
  color: var(--ink);
}


.viewer__stage {
  grid-column: 2;
  grid-row: 2;
  min-height: 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* the pages size themselves to whichever runs out first: height, or
   half the width (a spread) / all of it (a single page) */
.viewer__spread {
  height: 100%;
  width: 100%;
  container-type: size;   /* pages size from this box: whichever runs out first */
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: pan-y;
  -webkit-user-select: none;
          user-select: none;
}
.viewer__spread {
  --ratio: 978 / 1400;     /* set per project by script.js */
  --r: 0.6986;
}
.viewer__spread > * {
  /* --pw: this page's own width. Padding is set as a share of it, because
     cq units on the page itself would measure the whole spread */
  --pw: min(50cqw, 100cqh * var(--r));
  display: block;
  flex: none;
  width: var(--pw);
  height: auto;
  aspect-ratio: var(--ratio);
  background: var(--surface-sunk);
  box-shadow: 0 2px 6px rgba(25,25,23,.08), 0 18px 40px rgba(25,25,23,.12);
  animation: page-in .3s var(--ease-out);
}
.viewer__spread.is-single > * { --pw: min(100cqw, 100cqh * var(--r)); }
/* a hairline spine between the two pages */
.viewer__spread > * + * { box-shadow: inset 1px 0 0 rgba(25,25,23,.10), 0 2px 6px rgba(25,25,23,.08), 0 18px 40px rgba(25,25,23,.12); }
@keyframes page-in { from { opacity: .35; } }

.viewer__foot {
  position: relative;
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 12px;
}

/* the rule above the bar, drawn in crayon */
.viewer__rule {
  position: absolute;
  top: -4px;
  left: 0;
  width: 100%;
  height: 8px;
  overflow: visible;
  fill: none;
  stroke: #BCB5A3;
  stroke-width: 1.7;
  stroke-linecap: round;
}

.viewer__sections { display: flex; flex-wrap: wrap; gap: 4px 6px; }
.viewer__sections button {
  position: relative;
  padding: 6px 10px 9px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12.5px;
  color: var(--ink-3);
  cursor: pointer;
  transition: color .25s var(--ease);
}
.viewer__sections button:hover { color: var(--ink); }
.viewer__sections button[aria-current="true"] { color: var(--ink); }

/* the current section gets a crayon underline that draws itself in */
.viewer__underline {
  position: absolute;
  left: 7px;
  right: 7px;
  bottom: 1px;
  width: calc(100% - 14px);
  height: 7px;
  overflow: visible;
  fill: none;
  stroke: #E2B24A;
  stroke-width: 3.2;
  stroke-linecap: round;
  pointer-events: none;
}
/* dash 1, gap 2: hidden, the whole stroke sits inside the gap, so no
   stray round cap shows as a dot */
.viewer__underline path {
  stroke-dasharray: 1 2;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset .2s var(--ease);
}
.viewer__sections button[aria-current="true"] .viewer__underline path {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset .5s var(--ease-out) .05s;
}

.viewer__rights {
  margin-left: auto;
  font-size: 11.5px;
  letter-spacing: .02em;
  color: var(--ink-3);
  white-space: nowrap;
}
.viewer__pager { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.viewer__rights:not([hidden]) + .viewer__pager { margin-left: 0; }
.viewer__count {
  min-width: 6.5em;
  text-align: center;
  font-size: 12.5px;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
.viewer__step {
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: opacity .3s var(--ease);
}
.viewer__step:disabled { opacity: .3; cursor: default; }

@media (max-width: 1100px) {
  .viewer { grid-template-columns: minmax(0, 1fr); }
  .viewer__about { display: none; }
  .viewer__stage { grid-column: 1; }
}

@media (max-width: 720px) {
  .viewer { row-gap: 12px; padding: 18px; padding-bottom: max(18px, env(safe-area-inset-bottom)); }
  .viewer__sections { display: none; }
  .viewer__pager { margin: 0 auto; }
  .viewer__foot { flex-wrap: wrap; row-gap: 6px; }
  .viewer__rights { order: 1; width: 100%; margin: 0; text-align: center; }
  .viewer__rights:not([hidden]) + .viewer__pager { margin: 0 auto; }
}

/* ---------------------------------------------------------
   Article pages ("sheets") — HTML pages shown in the viewer
   like a printed feature. Everything is sized in container
   units (cqi = 1% of the page's width), so a sheet scales
   exactly like an image page does.
--------------------------------------------------------- */

.sheet {
  position: relative;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  padding: calc(var(--pw, 400px) * .09) calc(var(--pw, 400px) * .09) calc(var(--pw, 400px) * .07);
  overflow: hidden;
  background: var(--surface);
  color: var(--ink);
  text-align: left;
}

.sheet__kicker {
  font-size: 2.9cqi;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: 2.4cqi;
  border-bottom: 1px solid var(--line-strong);
}

.sheet__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 9.4cqi;
  line-height: 1.04;
  letter-spacing: -0.02em;
  margin-top: 4cqi;
}

.sheet__dek {
  font-family: var(--serif);
  font-size: 4.4cqi;
  line-height: 1.35;
  color: var(--ink-2);
  margin-top: 4.5cqi;
}

.sheet__art {
  width: 70cqi;
  aspect-ratio: 1;
  margin: 3cqi auto 0;
  overflow: visible;
}

/* --- full-text pages: the article as written --- */

.sheet--text { padding: calc(var(--pw, 400px) * .08) calc(var(--pw, 400px) * .085) calc(var(--pw, 400px) * .065); }

.sheet__top { display: flex; justify-content: space-between; align-items: flex-end; }
.sheet__no {
  font-family: var(--serif);
  font-size: 11cqi;
  line-height: .85;
  letter-spacing: -0.03em;
}
.sheet__icon { width: 17cqi; aspect-ratio: 1; overflow: visible; margin: -2cqi -1.5cqi 0 0; }

.sheet__head {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 5.8cqi;
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin-top: 3.6cqi;
  padding-bottom: 3cqi;
  border-bottom: 1px solid var(--line-strong);
}

.sheet__body {
  margin-top: 3.4cqi;
  display: flex;
  flex-direction: column;
  gap: 2cqi;
  font-size: 3.6cqi;
  line-height: 1.52;
  color: var(--ink-2);
}
.sheet__body strong { color: var(--ink); font-weight: 500; }
.sheet__body em { font-style: italic; }

.sheet__tip {
  margin-top: .6cqi;
  padding: 2.4cqi 3cqi;
  border-left: .7cqi solid var(--a-clay);
  background: var(--surface-sunk);
  font-size: 3.4cqi;
  line-height: 1.48;
}

.sheet__signoff { margin-top: 1cqi; font-family: var(--serif); font-size: 4.2cqi; line-height: 1.3; color: var(--ink); }

/* intro page: a serif lede and the five sections as contents */
.sheet--intro .sheet__body { margin-top: 5cqi; }
.sheet__lede { font-family: var(--serif); font-size: 5.6cqi; line-height: 1.25; color: var(--ink); }
.sheet__toc { margin-top: auto; border-top: 1px solid var(--line-strong); }
.sheet__toc li {
  display: grid;
  grid-template-columns: 7cqi 1fr;
  padding: 1.9cqi 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--serif);
  font-size: 3.7cqi;
  color: var(--ink);
}
.sheet__toc span { color: var(--ink-3); font-style: italic; }
.sheet--intro .sheet__foot { margin-top: 3cqi; }

/* phones get a taller page (see PROJECTS.japan.shape), so the text can be larger */
@media (max-width: 720px) {
  .sheet__body { font-size: 4.2cqi; gap: 2.4cqi; line-height: 1.5; }
  .sheet__tip { font-size: 3.95cqi; padding: 2.8cqi 3.4cqi; }
  .sheet__head { font-size: 7.4cqi; }
  .sheet__no { font-size: 13cqi; }
  .sheet .sheet__kicker, .sheet .sheet__foot { font-size: 3.4cqi; }   /* .sheet: outranks the base rules below */
  .sheet__signoff { font-size: 5cqi; }
  .sheet__lede { font-size: 6.4cqi; }
  .sheet--intro .sheet__body { margin-top: 4cqi; }
  .sheet__toc li { font-size: 4.3cqi; padding: 1.5cqi 0; }
}

.sheet__foot {
  margin-top: auto;
  padding-top: 3cqi;
  display: flex;
  justify-content: space-between;
  font-size: 2.8cqi;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.sheet--cover .sheet__foot { border-top: 1px solid var(--line); }

/* ---------------------------------------------------------
   M2M Tech deck — set in M2M Tech's brand (Lora headlines,
   Inter text, their yellow, black and warm white) the way a
   print designer would: flat colour, a grid, rules, and type
   doing the work. Sized in container units so a slide scales
   as one piece; 16:9 on desktop, portrait on phones.
--------------------------------------------------------- */

.m2m {
  --m-yellow: #FFDC14;
  --m-black:  #0B0A09;
  --m-ink:    #0F121A;
  --m-white:  #FBFAF8;
  --m-line:   rgba(15, 18, 26, .16);
  --m-lora:  "Lora", Georgia, serif;
  --m-inter: "Inter", ui-sans-serif, system-ui, sans-serif;

  position: relative;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  padding: calc(var(--pw, 800px) * .048) calc(var(--pw, 800px) * .054) calc(var(--pw, 800px) * .034);
  overflow: hidden;
  font-family: var(--m-inter);
  font-size: 1.5cqi;
  line-height: 1.5;
  text-align: left;
}
/* zero-specificity resets, so the m2m__ classes below always win */
:where(.m2m) :where(p, ul, ol, h3, h4, dl, dd, table) { margin: 0; }
:where(.m2m) :where(ul, ol) { list-style: none; padding: 0; }

.m2m--light  { background: var(--m-white); color: var(--m-ink); }
.m2m--dark   { background: var(--m-black); color: #F4F1EA; --m-line: rgba(244, 241, 234, .2); }
.m2m--yellow { background: var(--m-yellow); color: #000; --m-line: rgba(0, 0, 0, .3); }

.m2m__mark { font-family: var(--m-lora); font-weight: 700; font-size: 1.5cqi; letter-spacing: -0.01em; }
.m2m__title { font-family: var(--m-lora); font-weight: 700; font-size: 3.9cqi; line-height: 1.06; letter-spacing: -0.025em; max-width: 22ch; }
.m2m__intro { font-size: 1.75cqi; line-height: 1.45; max-width: 52ch; margin-top: 1.4cqi; opacity: .85; }
.m2m__label { font-size: 1.25cqi; font-weight: 600; }
.m2m__colhead { font-family: var(--m-lora); font-weight: 700; font-size: 1.95cqi; line-height: 1.2; margin-bottom: .8cqi; }
.m2m--dark p, .m2m--dark td { color: rgba(244, 241, 234, .82); }

.m2m__foot {
  margin-top: auto;
  padding-top: 1.8cqi;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 1.2cqi;
}
.m2m__foot span:last-child { opacity: .6; }

/* cover: a solid field of their yellow, type set large */
.m2m--cover .m2m__display {
  margin-top: auto;
  font-family: var(--m-lora);
  font-weight: 700;
  font-size: 8cqi;
  line-height: .98;
  letter-spacing: -0.035em;
  max-width: 9ch;
}
.m2m__sub { font-size: 1.8cqi; line-height: 1.4; max-width: 44ch; margin-top: 2.4cqi; }
.m2m--cover .m2m__foot { margin-top: 3.4cqi; padding-top: 1.4cqi; border-top: 1.5px solid #000; }
.m2m--cover .m2m__foot span:last-child { opacity: 1; }

/* three columns under a strong rule */
.m2m__cols { display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 3.6cqi; border-top: 1.5px solid currentColor; }
.m2m__cols > div { padding: 1.8cqi 2.4cqi 0 0; }
.m2m__cols > div + div { padding-left: 2.4cqi; border-left: 1px solid var(--m-line); }
.m2m__note { margin-top: 3.2cqi; padding-top: 1.4cqi; border-top: 1px solid var(--m-line); }
.m2m__note .m2m__label { margin-right: 1.2cqi; }

/* split: a black panel beside a definition list */
.m2m--split { flex-direction: row; padding: 0; }
.m2m__panel {
  flex: 0 0 46%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: calc(var(--pw, 800px) * .048) calc(var(--pw, 800px) * .044);
  background: var(--m-black);
  color: #F4F1EA;
}
.m2m__panel .m2m__label { color: var(--m-yellow); }
.m2m__panel .m2m__title { font-size: 6.4cqi; margin-top: 1cqi; }
.m2m__side { flex: 1; display: flex; flex-direction: column; padding: calc(var(--pw, 800px) * .048) calc(var(--pw, 800px) * .054) calc(var(--pw, 800px) * .034) calc(var(--pw, 800px) * .044); }
.m2m__defs { margin: auto 0; }
.m2m__defs > div { display: grid; grid-template-columns: 11cqi 1fr; gap: 2cqi; padding: 1.6cqi 0; border-top: 1px solid var(--m-line); }
.m2m__defs > div:last-child { border-bottom: 1px solid var(--m-line); }
.m2m__defs dt { font-weight: 600; font-size: 1.3cqi; }
.m2m__defs dd { font-size: 1.6cqi; line-height: 1.45; }

/* social audit: a plain table */
.m2m__table { width: 100%; margin-top: 3.6cqi; border-collapse: collapse; font-size: 1.62cqi; }
.m2m__table th, .m2m__table td { text-align: left; vertical-align: top; padding: 2.4cqi 2.4cqi 2.4cqi 0; border-top: 1px solid var(--m-line); }
.m2m__table thead th { padding: 0 2.4cqi 1cqi 0; border-top: 0; font-weight: 600; font-size: 1.2cqi; opacity: .7; }
.m2m__table tbody th { font-family: var(--m-lora); font-weight: 700; font-size: 2.4cqi; line-height: 1.2; white-space: nowrap; }
.m2m__table tbody tr:last-child > * { border-bottom: 1px solid var(--m-line); }
.m2m__table td:last-child { white-space: nowrap; padding-right: 0; }
.m2m__table tbody td:nth-child(3) { width: 52%; }
.m2m__hl { color: var(--m-yellow); font-weight: 600; }

/* scorecard: two numbered lists under coloured rules */
.m2m__compare { display: grid; grid-template-columns: 1fr 1fr; gap: 4cqi; margin-top: 3.4cqi; }
.m2m__side-a { border-top: .6cqi solid var(--m-yellow); padding-top: 1.6cqi; }
.m2m__side-b { border-top: .6cqi solid var(--m-ink); padding-top: 1.6cqi; }
.m2m__items { counter-reset: item; }
.m2m__items li { counter-increment: item; display: grid; grid-template-columns: 2.4cqi 1fr; gap: 1cqi; padding: 1.1cqi 0; border-bottom: 1px solid var(--m-line); font-size: 1.45cqi; }
.m2m__items li::before { content: counter(item); font-family: var(--m-lora); font-weight: 700; }

/* playbook: four columns, numbers in their yellow */
.m2m__moves { flex: 1; display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 3cqi; border-top: 1px solid var(--m-line); }
.m2m__moves li { padding: 2cqi 2.2cqi 0 0; font-size: 1.42cqi; }
.m2m__moves li + li { padding-left: 2.2cqi; border-left: 1px solid var(--m-line); }
.m2m__num { display: block; margin-bottom: 1.6cqi; font-family: var(--m-lora); font-weight: 700; font-size: 5cqi; line-height: 1; color: var(--m-yellow); }

/* preview in Work and on Home: a small copy of the yellow cover */
.art--m2m { background: #ECE9E2; }
.m2m-mini { position: absolute; inset: 0; display: grid; place-items: center; }
.m2m-mini__card {
  width: 76%;
  aspect-ratio: 16 / 9;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 5.5cqi 6cqi;
  background: #FFDC14;
  color: #000;
  box-shadow: 0 2px 6px rgba(25, 25, 23, .1), 0 14px 30px rgba(25, 25, 23, .12);
}
.m2m-mini__mark { font-family: "Lora", Georgia, serif; font-weight: 700; font-size: 5.5cqi; }
.m2m-mini__title { font-family: "Lora", Georgia, serif; font-weight: 700; font-size: 12.5cqi; line-height: .98; letter-spacing: -0.03em; max-width: 9ch; }

/* phones: each slide becomes a portrait card; columns stack, and text
   stays readable (labels >= ~9.5px, text ~11px on a 375px phone) */
@media (max-width: 720px) {
  .m2m { padding: calc(var(--pw, 340px) * .07) calc(var(--pw, 340px) * .07) calc(var(--pw, 340px) * .05); font-size: 3.9cqi; }
  .m2m__mark { font-size: 3.9cqi; }
  .m2m__title { font-size: 7.6cqi; }
  .m2m__intro { font-size: 4cqi; margin-top: 2.2cqi; }
  .m2m__label { font-size: 3.3cqi; }
  .m2m__colhead { font-size: 4.4cqi; margin-bottom: .6cqi; }
  .m2m__foot { font-size: 3.2cqi; padding-top: 2.4cqi; }

  .m2m--cover .m2m__display { font-size: 14cqi; }
  .m2m__sub { font-size: 4.2cqi; margin-top: 3.4cqi; }
  .m2m--cover .m2m__foot { margin-top: 5cqi; }

  .m2m__cols { grid-template-columns: 1fr; margin-top: 4cqi; }
  .m2m__cols > div,
  .m2m__cols > div + div { padding: 2.4cqi 0; border-left: 0; }
  .m2m__cols > div + div { border-top: 1px solid var(--m-line); }
  .m2m__cols p { font-size: 3.7cqi; line-height: 1.4; }
  .m2m__note { margin-top: 1cqi; padding-top: 2.4cqi; font-size: 3.6cqi; }

  .m2m--split { flex-direction: column; }
  .m2m__panel { flex: none; padding: calc(var(--pw, 340px) * .07); }
  .m2m__panel .m2m__title { font-size: 11cqi; }
  .m2m__side { padding: calc(var(--pw, 340px) * .04) calc(var(--pw, 340px) * .07) calc(var(--pw, 340px) * .05); }
  .m2m__defs > div { grid-template-columns: 22cqi 1fr; gap: 3cqi; padding: 2.4cqi 0; }
  .m2m__defs dt { font-size: 3.4cqi; }
  .m2m__defs dd { font-size: 3.8cqi; }

  .m2m__table, .m2m__table tbody { display: block; margin-top: 4cqi; }
  .m2m__table thead { display: none; }
  .m2m__table tbody tr { display: grid; grid-template-columns: auto 1fr; column-gap: 3cqi; padding: 2.6cqi 0; border-top: 1px solid var(--m-line); }
  .m2m__table tbody tr:last-child { border-bottom: 1px solid var(--m-line); }
  .m2m__table th, .m2m__table td, .m2m__table tbody tr:last-child > * { padding: 0; border: 0; font-size: 3.6cqi; line-height: 1.4; }
  .m2m__table tbody th { font-size: 4.6cqi; }
  .m2m__table td:nth-child(2) { align-self: center; font-size: 3.3cqi; opacity: .7; }
  .m2m__table tbody td:nth-child(3) { grid-column: 1 / -1; width: auto; margin-top: 1.2cqi; }
  .m2m__table td:last-child { grid-column: 1 / -1; margin-top: .8cqi; font-size: 3.3cqi; opacity: .6; }

  .m2m__compare { grid-template-columns: 1fr; gap: 4cqi; margin-top: 3.6cqi; }
  .m2m__side-a, .m2m__side-b { border-top-width: 1.4cqi; padding-top: 2.2cqi; }
  .m2m__items li { grid-template-columns: 4.6cqi 1fr; gap: 1.6cqi; padding: 1.6cqi 0; font-size: 3.5cqi; line-height: 1.38; }

  .m2m__moves { grid-template-columns: 1fr 1fr; margin-top: 3.4cqi; border-top: 0; }
  .m2m__moves li,
  .m2m__moves li + li { padding: 2.6cqi 2.6cqi 2.6cqi 0; border-left: 0; border-top: 1px solid var(--m-line); font-size: 3.3cqi; line-height: 1.38; }
  .m2m__moves li:nth-child(even) { padding-left: 2.6cqi; padding-right: 0; border-left: 1px solid var(--m-line); }
  .m2m__num { font-size: 8cqi; margin-bottom: 1.4cqi; }
}

/* ---------------------------------------------------------
   Tablet
--------------------------------------------------------- */

@media (max-width: 1100px) {
  .note--intro  { grid-column: 1 / span 6; }
  .shelf { grid-column: 1 / -1; }
  .note--currently { grid-column: 1 / span 5; }

  /* copy on the left; portrait over facts on the right, so nothing
     has to stack in one column on short tablet screens */
  .about        { grid-template-rows: minmax(0, 1fr) auto; row-gap: 20px; }
  .about__copy  { grid-column: 1 / span 6; grid-row: 1 / span 2; align-self: start; }
  .portrait     { grid-column: 8 / -1; grid-row: 1; }
  .about__facts { grid-column: 8 / -1; grid-row: 2; align-self: end; }

  .index   { grid-column: 1 / span 7; }
  .preview { grid-column: 8 / -1; }

  .contact__note  { grid-column: 1 / span 9; }
}

/* ---------------------------------------------------------
   Narrow: the one-row footer needs ~900px, so below that the
   dock takes its own row (still on a rule), © and clock beneath
--------------------------------------------------------- */

@media (max-width: 900px) {
  .footer {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "dock dock"
      "start end";
    row-gap: 12px;
    padding-top: 8px;
  }
  .footer__side--start { grid-area: start; }
  .footer__side--end   { grid-area: end; justify-content: flex-end; }
  .footer .footer__rule { display: none; }

  /* one full-width rule behind the dock keeps the "on the line" look */
  .dock {
    grid-area: dock;
    position: relative;
    display: flex;
    justify-content: center;
  }
  .dock::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 1px;
    background: var(--line-strong);
  }
}

/* ---------------------------------------------------------
   Phone — same four pages, fewer things on each
--------------------------------------------------------- */

@media (max-width: 720px) {
  /* phones: a page taller than the screen scrolls on its own, under a
     pinned footer (only About needs it); desktop never scrolls */
  .page {
    overflow-y: auto;
    overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch;
  }
  .page--about { grid-template-rows: auto auto; }
  .page--about .page__body { min-height: auto; padding-bottom: 32px; }   /* grows with its copy; the last line clears the dock */

  .page__body { grid-template-columns: minmax(0, 1fr); }

  .home { grid-template-rows: auto auto minmax(0, 1fr); align-content: start; }
  .note--intro, .shelf, .note--currently { grid-column: 1; }
  .note--intro  { grid-row: 1; margin-top: 24px; }
  .shelf        { grid-row: 2; align-self: start; margin-top: 28px; }
  .shelf__row   { gap: 8px; }
  .doodle__icon { width: clamp(52px, 15vw, 72px); margin-bottom: 6px; }
  .doodle__title { font-size: 14px; white-space: normal; }
  .doodle__meta  { display: none; }
  .note--currently { display: none; }

  .about { grid-template-rows: auto auto; align-content: start; padding-top: 24px; row-gap: 28px; }
  .about__copy, .about__facts { grid-column: 1; grid-row: auto; align-self: start; }
  .portrait { display: none; }

  .work { grid-template-rows: auto; align-content: center; padding-top: 0; }
  .index { grid-column: 1; align-self: center; }
  .index__row { grid-template-columns: 2.4em 1fr; }
  .index__meta { grid-column: 2; }
  .preview { display: none; }

  .contact { padding-top: 24px; }
  .contact__note { grid-column: 1; }



  .dock__link { min-width: 0; padding: 8px 14px; font-size: 12.5px; }
  .clock { gap: 8px; }
  .clock__time { min-width: 7.8em; }   /* fits "12:59:59 PM PDT", so it never shifts */
}

@media (max-width: 359px) {
  .display__candy { width: .36em; height: .36em; margin-left: .1em; }   /* keeps the name on one line */
}

/* short phones (iPhone SE and the like): a little tighter */
@media (max-width: 720px) and (max-height: 740px) {
  .about { padding-top: 16px; row-gap: 20px; }
  .note--intro { margin-top: 16px; }
}

/* short laptop screens */
@media (min-width: 721px) and (max-height: 760px) {
  .about__extra { display: none; }
  .note p:not(.lede) { font-size: 14px; }
  .note .lede { font-size: clamp(19px, 1.5vw, 23px); }
}

@media (min-width: 721px) and (max-height: 620px) {
  .note--currently { display: none; }
}

/* ---------------------------------------------------------
   No JS: let the pages simply stack and scroll
--------------------------------------------------------- */

.no-js, .no-js body { height: auto; overflow: auto; }
.no-js .app { height: auto; }
.no-js .page { position: relative; inset: auto; opacity: 1; visibility: visible; min-height: 100vh; }
.no-js .rise, .no-js .display__text { opacity: 1; transform: none; }
.no-js .dock { visibility: hidden; }

/* ---------------------------------------------------------
   Reduced motion
--------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }
}

/* ---------------------------------------------------------
   Crayon landscape — the living background

   Animated like a flipbook. script.js works out every doodle's
   pose for each tick (6 a second) and hands the browser the whole
   sequence up front, as an ordinary transform/opacity animation in
   which each pose holds for a tick and then jumps. Because those
   are plain (non-stepped) transform and opacity animations, Safari
   runs them on iOS's compositor, which keeps animating even when
   the page itself is barely repainting. Anything driven from the
   page each tick (CSS steps(), seeking paused animations, a
   requestAnimationFrame loop) only redrew once a second on iPhone.

   The line boil and the wing flap are the same trick on opacity:
   each doodle has three drawings, each bird a wings-up and a
   wings-down drawing, and only one shows at a time.

   Positions below are the still frame shown without JS and with
   "reduce motion" on.
--------------------------------------------------------- */

.scene-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.scene {
  --band: clamp(130px, 28vh, 320px);   /* height of the landscape strip */

  /* crayon box: the site palette, pushed a little so it reads as wax */
  --c-sun:    #E2B24A;
  --c-cloud:  #8EA7CF;
  --c-lilac:  #ADA0D8;
  --c-hill-b: #A7BF9C;
  --c-hill-f: #7FA27A;
  --c-leaf:   #6E9A6A;
  --c-leaf-2: #8DB07F;
  --c-bird:   #6B6F86;
  --c-pink:   #E39AA6;
  --c-clay:   #E39E7E;

  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: .46;
}

.scene svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 7.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sky, .land { position: absolute; }
.sky  { inset: 0; }
.land { left: 0; right: 0; bottom: 0; height: var(--band); }

/* every moving part gets its own compositor layer */
.sun__rays, .sun__core, .cloud, .flock, .bird, .tree, .flower, .star {
  will-change: transform;
}
.boil-frame, .bird__pose { will-change: opacity; }

/* --- sun: rays turn slowly, the disc breathes --- */

.sun {
  position: absolute;
  top: 5%;
  right: 5%;
  width: clamp(84px, 11vmin, 140px);
  aspect-ratio: 1;
  color: var(--c-sun);
}
.sun__rays, .sun__core { position: absolute; inset: 0; }

/* --- clouds drift across, each at its own pace --- */

.cloud {
  position: absolute;
  left: 0;
  width: clamp(110px, 13vw, 210px);
  aspect-ratio: 180 / 96;
}
.cloud svg { stroke-width: 6; }
.cloud--1 { top: 9%;  color: var(--c-cloud); transform: translateX(8vw); }
.cloud--2 { top: 21%; color: var(--c-lilac); transform: translateX(46vw); width: clamp(90px, 10vw, 160px); }
.cloud--3 { top: 33%; color: var(--c-cloud); transform: translateX(70vw); width: clamp(80px, 8vw, 130px); }

/* --- a small flock crosses every so often --- */

.flock {
  position: absolute;
  top: 15%;
  left: 0;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: var(--c-bird);
  transform: translate(52vw, 0);
}
.bird {
  position: relative;
  display: block;
  width: clamp(32px, 3.2vw, 50px);
  aspect-ratio: 44 / 26;
}
.bird--2 { width: clamp(24px, 2.4vw, 38px); margin-top: 22px; }
.bird--3 { width: clamp(27px, 2.7vw, 42px); margin-top: -8px; }
.scene .bird__pose { position: absolute; inset: 0; stroke-width: 4.5; }
.scene .bird__pose--down { opacity: 0; }   /* wings-down drawing, made by script.js */

/* --- stars twinkle --- */

.star {
  position: absolute;
  width: clamp(14px, 1.6vw, 22px);
  aspect-ratio: 1;
  color: var(--c-sun);
}
.star svg { stroke-width: 2; }
.star--1 { top: 11%; left: 47%; }
.star--2 { top: 29%; left: 71%; width: clamp(11px, 1.2vw, 16px); }
.star--3 { top: 41%; left: 36%; width: clamp(10px, 1vw, 14px); }

/* --- the land: hills are static, trees and flowers sway --- */

.hills { position: absolute; inset: 0; }
.hills__back  { stroke: var(--c-hill-b); stroke-width: 9; }
.hills__front { stroke: var(--c-hill-f); stroke-width: 9; }
.hills__grass { stroke: var(--c-hill-f); stroke-width: 6; }

.tree {
  position: absolute;
  bottom: 44%;               /* stands on the back hill */
  height: clamp(84px, 17vh, 190px);
  transform-origin: 50% 100%;
}
.tree svg { width: auto; }
.tree--1 { left: 3%;   aspect-ratio: 130 / 170; color: var(--c-leaf); }
.tree--2 { left: 12%;  aspect-ratio: 110 / 170; color: var(--c-leaf-2); height: clamp(64px, 12vh, 140px); }
.tree--3 { right: 7%;  aspect-ratio: 130 / 170; color: var(--c-leaf-2); }
.tree--4 { right: 18%; aspect-ratio: 110 / 170; color: var(--c-leaf); height: clamp(58px, 11vh, 120px); }

.flower {
  position: absolute;
  bottom: 6%;
  height: clamp(40px, 7vh, 80px);
  aspect-ratio: 64 / 100;
  transform-origin: 50% 100%;
}
.flower svg { stroke-width: 5.5; }
.flower--1 { left: 24%;  color: var(--c-pink); }
.flower--2 { left: 38%;  color: var(--c-lilac); height: clamp(34px, 5.5vh, 64px); }
.flower--3 { right: 30%; color: var(--c-clay); }
.flower--4 { right: 3%;  color: var(--c-pink);  height: clamp(34px, 5.5vh, 64px); }

/* --- line boil: three drawings of each doodle (script.js makes the
       extra two); the animations show one at a time --- */

.scene .boil-1,
.scene .boil-2 { position: absolute; inset: 0; opacity: 0; }

/* phones and touch screens: no live blur behind the dock. Re-blurring an
   animated background every frame is expensive on iOS */
@media (max-width: 720px), (pointer: coarse) {
  .dock__track {
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    background: rgba(255, 255, 255, .94);
  }
}

/* phones: a lighter sketch */
@media (max-width: 720px) {
  .scene { --band: clamp(120px, 22vh, 200px); opacity: .4; }
  .tree--2, .tree--4, .flower--2, .flower--3, .cloud--3, .star--3 { display: none; }
  .tree--1 { left: -2%; }
  .tree--3 { right: -1%; }
  .sun { top: 3%; right: 4%; }
}

/* ---------------------------------------------------------
   Placeholder artwork — pure CSS, swap for real images later
--------------------------------------------------------- */

.art { display: block; }

.art__blob {
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  filter: blur(26px);
}

/* 02 — fine grid field with a few filled tiles */
.art--2 {
  background-color: #FCFBF8;
  background-image:
    linear-gradient(to right,  var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size: 44px 44px;
  background-position: -1px -1px;
}
.art__tile { position: absolute; width: 44px; height: 44px; border-radius: 3px; }
.art__tile--1 { left: 87px;  top: 131px; background: var(--a-clay);   opacity: .9; }
.art__tile--2 { left: 131px; top: 175px; background: var(--a-sky);    opacity: .85; }
.art__tile--3 { left: 219px; top: 131px; background: var(--a-butter); }

/* 04 — stacked sheets */
.art--4 { background: linear-gradient(160deg, #F7F5F0, #EDE8DE); }
.art__sheet {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 62%;
  aspect-ratio: 3 / 4;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.art__sheet--back  { transform: translate(-50%, -52%) rotate(-9deg);   background: var(--a-butter); }
.art__sheet--mid   { transform: translate(-50%, -51%) rotate(-3.5deg); background: #FDFBF6; }
.art__sheet--front { transform: translate(-56%, -48%) rotate(3deg); }
