/* =========================================================
   mathew-mullen.com — main stylesheet
   See /docs/design/design-direction.md for the design rules.
   ========================================================= */

/* Inter, self-hosted: no third-party request on page load. Upright variable
   face only — the site uses no italics. SIL Open Font License, see
   assets/fonts/Inter-LICENSE.txt. */
@font-face {
  font-family: 'Inter var';
  src: url('../assets/fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../assets/fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg-primary:  #DBD5C3;
  /* One block colour everywhere (chosen with tools/color-picker.js). The card
     and deep variants are kept in content so a second colour can come back,
     but both currently resolve to the same value. Was #F4EFE6 / #C8B998. */
  --bg-block:    #EDE8CE;
  --bg-card:     var(--bg-block);
  --bg-deep:     var(--bg-block);
  --bg-seam:     #C9BE9E;  /* the second of two touching blocks */
  --bg-ink:      #000000;
  --ink:         #202020;
  --ink-muted:   #5A5A57;
  --accent-red:  #F25F5C;
  --accent-blue: #247BA0;

  --stripe: 3px;
  /* Side padding grows on very wide screens so content caps at --page-max and centres. */
  --page-max: 1440px;
  --pad-x: max(clamp(24px, 6vw, 96px), calc((100vw - var(--page-max)) / 2));
  /* Detail pages use a narrower, centred column. */
  --detail-max: 1200px;
  --detail-x: max(var(--pad-x), calc((100% - var(--detail-max)) / 2));
  --pad-section-y: clamp(64px, 12vw, 160px);
  --pad-block-y: clamp(48px, 8vw, 120px);

  --display: clamp(48px, 8vw, 120px);
  --h2: clamp(32px, 4vw, 56px);

  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

@supports (font-variation-settings: normal) {
  :root { --font-sans: 'Inter var', -apple-system, BlinkMacSystemFont, sans-serif; }
}

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

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-primary);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; transition: opacity 120ms ease; }
a:hover { opacity: 0.65; }

h1, h2, h3, p { margin: 0; }

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

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

.site-header {
  position: relative;
  background: var(--bg-primary);
}

.stripes {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.stripe {
  height: var(--stripe);
  width: 100%;
}

.stripe--red  { background: var(--accent-red); }
.stripe--blue { background: var(--accent-blue); margin-top: var(--stripe); }

.site-header__bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 24px var(--pad-x);
}

.site-logo {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  background: var(--bg-primary);
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 20px;
  line-height: 1;
  flex-shrink: 0;
  /* Flex centring centres the line box, not the ink. A lowercase m has no
     ascender or descender, so it sat 1.8px low; lift it onto the true centre.
     The left stem's spur also makes it read left-heavy (and Safari renders it
     ~0.5px left), so nudge it right by the same half pixel. */
  padding-bottom: 0.18em;
  padding-left: 0.05em;
}
.site-logo:hover { opacity: 1; background: var(--ink); color: var(--bg-primary); }

.site-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  margin-left: 4px;
}
.site-name { font-weight: 500; font-size: 15px; }
.site-year { font-size: 13px; color: var(--ink-muted); }

.site-nav {
  margin-left: auto;
  display: flex;
  gap: 28px;
  font-size: 15px;
  font-weight: 500;
}

@media (max-width: 600px) {
  .site-nav { gap: 18px; font-size: 14px; }
  .site-meta { display: none; }
}

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

.hero {
  padding: clamp(48px, 9vw, 120px) var(--pad-x) clamp(64px, 10vw, 140px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.hero__super {
  font-size: 20px;
  font-weight: 500;
  color: var(--ink-muted);
}

.hero__title {
  font-size: var(--display);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 0.95;
}

.hero__sub {
  font-size: clamp(20px, 2.4vw, 28px);
  font-weight: 400;
  line-height: 1.4;
  max-width: 28ch;
  margin-top: 16px;
  color: var(--ink);
}

/* ---------- Work ---------- */

.work {
  display: flex;
  flex-direction: column;
}

.project {
  padding: var(--pad-block-y) var(--pad-x);
  position: relative;
}

.project__title a {
  color: inherit;
  text-decoration: none;
}

.project__canvas-link {
  display: block;
  width: calc(100% - clamp(40px, 10vw, 160px));
}
.project__canvas-link:hover { opacity: 1; }

.project__head {
  width: calc(100% - clamp(40px, 10vw, 160px));
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  align-items: start;
  margin-bottom: 48px;
}

.project__title {
  font-size: var(--h2);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
}

.project__lede {
  font-size: 18px;
  line-height: 1.5;
  color: var(--ink);
  max-width: 40ch;
  align-self: end;
  justify-self: end;
}

.project__canvas {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(32px, 5vw, 80px);
}

.project__canvas--card { background: var(--bg-card); }
.project__canvas--deep { background: var(--bg-deep); }
/* Brand mark, bottom-left of the canvas. Small enough to be a signature, not a logo wall. */
.project__mark {
  position: absolute;
  left:   clamp(14px, 1.7vw, 26px);
  bottom: clamp(14px, 1.7vw, 26px);
  width:  clamp(22px, 2.3vw, 34px);
  height: auto;
  z-index: 5;
  pointer-events: none;
}
.project__mark--icon  { border-radius: 22.5%; }
.project__mark--glyph { opacity: 0.88; }
/* monochrome glyphs are drawn in ink; flip them on the black canvas */
.project__canvas--ink .project__mark--glyph { filter: invert(1); }

/* For media that already carries a black composite background — blends seamlessly */
.project__canvas--ink  { background: var(--bg-ink); }

.project__foot {
  width: calc(100% - clamp(40px, 10vw, 160px));
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  margin-top: 32px;
  gap: 24px;
}

.project__meta {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.project__link {
  font-size: 15px;
  font-weight: 500;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 2px;
}

@media (max-width: 700px) {
  .project__head { width: 100%; grid-template-columns: 1fr; gap: 16px; margin-bottom: 32px; }
  .project__foot { width: 100%; grid-template-columns: 1fr; gap: 16px; }
  .project__canvas-link { width: 100%; }
  /* The head collapses to one column here, so the lede must stop hugging
     the right edge — invisible on a phone where 40ch fills the column,
     obvious once the column is wider than the copy. */
  .project__lede { justify-self: start; }
  .project__canvas {
    width: 100%;
    aspect-ratio: 4 / 5;
    padding: clamp(24px, 5vw, 48px);
  }
}

/* Tweener — wider than a phone, narrower than the two-column head.
   A 4/5 canvas at this width strands the media in a tall empty block,
   so the canvas goes landscape and the wide composite grows to match. */
@media (min-width: 560px) and (max-width: 700px) {
  .project__canvas { aspect-ratio: 16 / 10; }
  .device--pre-framed--wide { width: 44vw; }
}

/* ---------- Device frames ---------- */

.devices {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 3vw, 40px);
  width: 100%;
}

.device {
  flex-shrink: 0;
}

.device--iphone {
  width: clamp(180px, 22vw, 280px);
  aspect-ratio: 9 / 19.5;
  border-radius: 36px;
  background: var(--ink);
  padding: 6px;
  box-shadow:
    0 24px 48px -16px rgba(32, 32, 32, 0.22),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.device__screen {
  width: 100%;
  height: 100%;
  border-radius: 30px;
  background: var(--bg-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
  font-size: 18px;
  color: var(--ink-muted);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}

.device__screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.device__screen--placeholder::before {
  content: '';
  width: 56px;
  height: 4px;
  background: var(--ink-muted);
  opacity: 0.2;
  border-radius: 2px;
  margin-right: 12px;
}

/* slightly smaller phone when paired so two fit comfortably */
.devices--pair .device--iphone {
  width: clamp(140px, 18vw, 230px);
}

/* asymmetric Y-offset for the Artem stagger */
.devices--pair .device:nth-child(1) { transform: translateY(-3%); }
.devices--pair .device:nth-child(2) { transform: translateY(6%); }
.devices--pair .device:nth-child(3) { transform: translateY(-3%); }

@media (max-width: 600px) {
  .devices--pair { gap: 12px; }
  .devices--pair .device--iphone { width: 38vw; }
  .devices--pair .device:nth-child(1) { transform: translateY(-2%); }
  .devices--pair .device:nth-child(2) { transform: translateY(4%); }
}

/* ---------- About ---------- */

/* Modelled on mikematas.com: a short paragraph and quiet links beside a black-and-white photo. */
.about {
  padding: var(--pad-section-y) var(--pad-x);
  display: grid;
  gap: 40px;
  font-size: clamp(20px, 2vw, 24px);
  line-height: 1.45;
}

@media (min-width: 860px) {
  .about {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: clamp(48px, 6vw, 96px);
    align-items: center;   /* the paragraph sits on the photo's vertical centre */
  }
}

.about__text { display: flex; flex-direction: column; gap: 40px; max-width: 34ch; }
.about__text p a { border-bottom: 1px solid var(--ink); padding-bottom: 1px; }
.about__cta { color: var(--ink-muted); }

.about__photo { margin: 0; }
.about__photo img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: 50% 70%;   /* favour faces over sky in phone selfies */
  /* Black and white with a little dust: a light sepia over full grayscale, to sit with the warm page. */
  filter: grayscale(1) sepia(var(--about-sepia, 0.15)) contrast(1.04);
}
.about__photo.is-color img { filter: none; }

/* ---------- Case Study (project detail page) ---------- */

.case-study {
  display: flex;
  flex-direction: column;
}

.case-hero {
  padding: var(--pad-section-y) var(--detail-x) var(--pad-block-y);
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.case-hero__title {
  font-size: var(--display);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 0.95;
  display: flex;
  align-items: center;
  gap: 0.25em;
}

.case-hero__lede {
  font-size: clamp(20px, 1.8vw, 24px);
  line-height: 1.45;
  max-width: 52ch;
  color: var(--ink);
}

.case-hero__back {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
  display: inline-block;
  margin-bottom: 32px;
}

.case-meta {
  margin-bottom: var(--pad-block-y);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px;
  border-top: 1px solid var(--ink);
  padding-top: 32px;
}

.case-meta--team {
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}

.case-meta dt {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 8px;
}

.case-meta dd {
  margin: 0;
  font-size: 16px;
  line-height: 1.45;
}

.case-section {
  margin: 0 var(--detail-x);
  padding: var(--pad-block-y) 0;
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
}

.case-section__heading {
  font-size: clamp(20px, 1.8vw, 24px);
  font-weight: 500;
  position: sticky;
  top: 24px;
}

.case-section__body {
  font-size: 18px;
  line-height: 1.6;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.case-section__body ul {
  margin: 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.case-visual {
  margin: 0 var(--detail-x);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(40px, 7vw, 96px) clamp(48px, 8vw, 120px);
}

.case-study > .case-visual:last-child {
  margin-bottom: var(--pad-section-y);
}

.case-visual--card { background: var(--bg-card); }
/* Blocks share one colour, so where two touch the second takes the seam
   colour. That keeps them reading as two blocks without a gap between them. */
.case-visual + .case-visual { background: var(--bg-seam); }
.case-visual--deep { background: var(--bg-deep); }
.case-visual--ink  { background: var(--bg-ink); }

.case-visual--full .device--iphone {
  width: clamp(220px, 28vw, 340px);
}

/* Flat editorial photo — sits on the background like artem */
.case-visual__photo {
  width: 100%;
  display: flex;
  justify-content: center;
}

.case-visual__photo img,
.case-visual__photo video {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}

/* Media that arrives with its own device chrome and black backing sits
   larger in the block than CSS-framed devices do. Pull it back to match. */
/* ---------- Prose links ---------- */
/* Citations inside case-study body copy. The global `a` rule strips all
   affordance, which is right for nav and card links and wrong here: a
   reference nobody can see is not a reference. Underline only, in ink. */
.case-section__body a {
  border-bottom: 1px solid rgba(32, 32, 32, 0.35);
  padding-bottom: 1px;
  transition: border-color 120ms ease;
}

.case-section__body a:hover {
  opacity: 1;
  border-bottom-color: var(--ink);
}

.case-visual--ink .case-visual__photo img,
.case-visual--ink .case-visual__photo video {
  max-width: 70%;
  border-radius: 0;
}

.case-visual__photo-pair {
  width: 100%;
  display: flex;
  gap: clamp(12px, 2vw, 32px);
  justify-content: center;
  align-items: flex-start;
}

.case-visual__photo-pair img {
  width: calc(50% - clamp(6px, 1vw, 16px));
  height: auto;
  display: block;
  border-radius: 4px;
}

/* CSS-layered frame: asset sits underneath, frame PNG overlaid via z-index */
.device--framed {
  position: relative;
  width: clamp(180px, 22vw, 280px);
  overflow: visible;
}

.device--framed--ipad {
  width: clamp(260px, 36vw, 500px);
}

.device--framed--mac {
  width: clamp(420px, 68vw, 860px);
}

.devices--overlap .device--framed--ipad {
  width: clamp(320px, 44vw, 580px);
}

.devices--pair .device--framed {
  width: clamp(140px, 18vw, 230px);
}

.device__frame-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
  display: block;
}

/* A powered-off screen: sits behind the media so the lockup is complete before
   anything has loaded, and stays dark if a screenshot never arrives. */
.device__screen-off {
  background: #000;
}

/* Media fades in over the dark screen once decoded (set by scripts/main.js).
   Scoped to .js so nothing is ever hidden when scripts don't run. */
.js [data-fade] {
  opacity: 0;
  transition: opacity 0.45s ease;
}

.js [data-fade].is-loaded {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-fade] { transition: none; }
}

@media (max-width: 600px) {
  .devices--pair .device--framed { width: 38vw; }
  .devices--overlap .device--framed--ipad { width: 50vw; }
  .device--framed--mac { width: calc(100vw - 32px); }
}

/* Pre-framed images already include device chrome — no CSS frame applied */
.device--pre-framed {
  width: clamp(180px, 22vw, 280px);
}

.device--pre-framed img {
  width: 100%;
  height: auto;
  display: block;
}

.devices--pair .device--pre-framed {
  width: clamp(140px, 18vw, 230px);
}

.device--pre-framed--small {
  width: clamp(90px, 11vw, 140px);
}

/* Wide composites — pre-framed media containing more than one device.
   Scaled to ~0.71 so the devices inside read at the same size as the
   CSS-framed devices on other projects (measured: 63.7% -> 45.3% of block). */
.device--pre-framed--wide {
  width: clamp(220px, 36vw, 505px);
}

.devices--pair .device--pre-framed--small {
  width: clamp(70px, 9vw, 115px);
}

.devices--pair--reverse .device:nth-child(1) { transform: translateY(6%); }
.devices--pair--reverse .device:nth-child(2) { transform: translateY(-3%); }

/* iPad + iPhone overlap composition */
.devices--overlap {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* Negative margins below do the spacing; a flex gap fights them. */
  gap: 0;
}

/* Overlap compositions follow Apple's product-family layout: the smallest
   device sits front-left, the largest behind-right, every device shares one
   floor, and each tucks behind the next with no background between them.

   Sizes are matched on TRUE PHYSICAL HEIGHT, which is how Apple scales these.
   Measured from their reference, iPhone/iPad height ratio is 0.845 — exactly
   the real 150mm / 177.5mm. Converted through each bezel's aspect ratio.

   :nth-last-child() guards keep the two- and three-device cases separate. */

/* ---- two devices ---- */
.devices--overlap .device:nth-child(1):nth-last-child(2) {
  z-index: 2;
  transform: none;
  width: clamp(64px, 12.2vw, 168px);
}

.devices--overlap .device:nth-child(2):nth-last-child(1) {
  z-index: 1;
  transform: none;
  width: clamp(220px, 42vw, 580px);
  margin-left: clamp(-19px, -1.3vw, -6px);
}


/* Pre-composited device images include transparent padding around the device,
   so edge-to-edge in the box is not edge-to-edge on screen. Measured on the
   Yuby assets: 8.7% per side on the phone, 6.1% on the iPad — about 50px at
   desktop scale. Pull them together by that much more. */
.devices--overlap .device--pre-framed:nth-child(2):nth-last-child(1) {
  margin-left: clamp(-69px, -4.6vw, -25px);
}

/* A screen with no device around it — a car head unit, where no bezel asset
   exists and inventing one would be a lie. Rounded corners and a hairline rim
   are enough to read it as a display rather than a pasted screenshot. */
.device--pre-framed--display img,
.device--pre-framed--display video {
  border-radius: clamp(5px, 0.9vw, 11px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.10);
}

/* Paired with a phone: the display sits back-right, the phone front-left,
   both on one floor. Specificity matches the nth-child rules above so the
   display keeps its own width. */
.devices--overlap .device--pre-framed--display:nth-child(2):nth-last-child(1) {
  z-index: 1;
  width: clamp(190px, 37vw, 470px);
  margin-left: clamp(-30px, -2.2vw, -12px);
}

/* Phone + laptop. A laptop is far taller than a tablet relative to a phone:
   measured on these renders, the MacBook's visible height is ~189mm against
   the iPhone's ~152mm, so under the physical-height rule the phone is ~24% of
   the laptop's frame width rather than the ~29% it takes beside an iPad. */
.devices--overlap:has(.device--framed--mac) .device:nth-child(1):nth-last-child(2) {
  width: clamp(52px, 10vw, 138px);
}

.devices--overlap:has(.device--framed--mac) .device:nth-child(2):nth-last-child(1) {
  margin-left: clamp(-42px, -3vw, -16px);
}

/* ---- three devices ---- */
.devices--overlap .device:nth-child(1):nth-last-child(3) {
  z-index: 3;
  transform: none;
  width: clamp(60px, 12.0vw, 167px);
}

.devices--overlap .device:nth-child(2):nth-last-child(2) {
  z-index: 2;
  transform: none;
  width: clamp(70px, 13.9vw, 195px);
  margin-left: clamp(-68px, -4.87vw, -24px);
}

.devices--overlap .device:nth-child(3):nth-last-child(1) {
  z-index: 1;
  transform: none;
  width: clamp(200px, 40vw, 560px);
  margin-left: clamp(-168px, -12vw, -60px);
}

.device--pre-framed--ipad {
  width: clamp(260px, 36vw, 500px);
}

/* iPhone in overlap — secondary element */
.devices--overlap .device--pre-framed:not(.device--pre-framed--ipad) {
  width: clamp(160px, 20vw, 260px);
}

/* iPad in overlap — dominant element, larger override */
.devices--overlap .device--pre-framed--ipad {
  width: clamp(320px, 44vw, 580px);
}

@media (max-width: 600px) {
  .devices--overlap .device--pre-framed--ipad { width: 50vw; }
  .devices--overlap .device--pre-framed:not(.device--pre-framed--ipad) { width: 28vw; }
}

.case-visual--full .device--pre-framed {
  width: clamp(220px, 28vw, 340px);
}

@media (max-width: 800px) {
  .case-meta { grid-template-columns: repeat(2, 1fr); }
  .case-section { grid-template-columns: 1fr; gap: 24px; }
  .case-section__heading { position: static; }
  .case-visual {
    margin: 0;
    max-width: none;
    width: 100%;
    padding: clamp(32px, 6vw, 64px);
  }
}

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

.site-footer {
  padding: 48px var(--pad-x) 64px;
  border-top: 1px solid var(--ink);
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
}

.site-footer ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  font-size: 15px;
  font-weight: 500;
}

.site-footer__copy {
  font-size: 13px;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
}

/* Trademark attribution — public build only. */
.site-footer__legal {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-muted);
  max-width: 62ch;
}

/* Three in a row (a sequence rather than a pair): narrower on phones so the row fits. */
@media (max-width: 600px) {
  .devices--pair:has(> .device:nth-child(3)) .device--framed { width: 27vw; }
  .devices--pair:has(> .device:nth-child(3)) { gap: 8px; }
}

/* ---------- Index card sizing ----------
   Lockups on index cards are sized in cqw — a share of the card's own width —
   so every card holds its devices with the same breathing room at every screen
   size. Vw-based clamps drifted: landscape lockups hit their pixel floors on
   phones and sat small in a tall card while portrait pairs filled theirs.
   Target: the lockup's dominant dimension fills ~76% of the card. Proportions
   between devices are the physical-height ratios from the overlap rules above. */
.project__canvas-link { container-type: inline-size; }

.project__canvas-link .devices--pair { gap: 3.5cqw; }
.project__canvas-link .devices--pair .device--framed,
.project__canvas-link .devices--pair .device--pre-framed:not(.device--pre-framed--small) { width: 22.7cqw; }
.project__canvas-link .devices--pair .device--pre-framed--small { width: 11.3cqw; }

/* phone + iPad */
.project__canvas-link .devices--overlap:has(.device--framed--ipad) .device:nth-child(1):nth-last-child(2) { width: 17.5cqw; }
.project__canvas-link .devices--overlap:has(.device--framed--ipad) .device:nth-child(2):nth-last-child(1) { width: 60.2cqw; margin-left: -1.87cqw; }
/* phone + car display */
.project__canvas-link .devices--overlap:has(.device--pre-framed--display) .device:nth-child(1):nth-last-child(2) { width: 20.1cqw; }
.project__canvas-link .devices--overlap:has(.device--pre-framed--display) .device:nth-child(2):nth-last-child(1) { width: 59.7cqw; margin-left: -3.63cqw; }
/* phone + laptop */
.project__canvas-link .devices--overlap:has(.device--framed--mac) .device:nth-child(1):nth-last-child(2) { width: 15.5cqw; }
.project__canvas-link .devices--overlap:has(.device--framed--mac) .device:nth-child(2):nth-last-child(1) { width: 64.9cqw; margin-left: -4.64cqw; }
/* pre-composited phone + iPad (transparent padding baked into the images) */
.project__canvas-link .devices--overlap:has(.device--pre-framed--ipad) .device:nth-child(1):nth-last-child(2) { width: 18.6cqw; }
.project__canvas-link .devices--overlap:has(.device--pre-framed--ipad) .device:nth-child(2):nth-last-child(1) { width: 64cqw; margin-left: -7cqw; }

/* Phones: portrait pairs keep the tall card; landscape lockups keep the
   landscape card they have everywhere else instead of floating in a tall one. */
@media (max-width: 559px) {
  .project__canvas:has(.devices--overlap) { aspect-ratio: 16 / 10; }
  .project__canvas-link .devices--pair .device--framed { width: 38cqw; }
  /* pre-composited pair images carry transparent padding, so they run larger */
  .project__canvas-link .devices--pair .device--pre-framed:not(.device--pre-framed--small) { width: 47cqw; }
  .project__canvas-link .devices--pair .device--pre-framed--small { width: 23.5cqw; }
}
