/* ============================================================
   Bennett — Portfolio
   Shared stylesheet
   ============================================================ */

/* ── Local font ───────────────────────────────────────────── */

@font-face {
  font-family: 'Lexend';
  src: url('fonts/Lexend/Lexend-VariableFont_wght.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ── Reset ──────────────────────────────────────────────── */

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

/* ── Tokens ─────────────────────────────────────────────── */

:root {
  --text:        #111;
  --muted:       #999;
  --faint:       #ccc;
  --link:        #111;
  --bg:          #fff;
  --rule:        #e8e8e8;
  --surface:     #f5f5f5;
  --surface-dark:#111;

  --font:        'Lexend', -apple-system, BlinkMacSystemFont, sans-serif;

  --size-xs:     0.72rem;   /* 11px */
  --size-sm:     0.8rem;    /* 12.8px */
  --size-base:   0.9375rem; /* 15px */
  --size-lg:     1.0625rem; /* 17px */
  --size-xl:     1.375rem;  /* 22px */

  --max-width:   640px;
  --gap:         1rem;
  --radius:      5px;

  --weight-regular: 400;
  --weight-subtle:  380;
  --weight-subhead: 430;
  --weight-title:   470;

  /* Motion — one easing, three durations. Keep everything cohesive. */
  --ease:      cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io:   cubic-bezier(0.4, 0, 0.2, 1);
  --dur-fast:  140ms;
  --dur-base:  220ms;
  --dur-slow:  340ms;
}

/* Opt-in for transitioning to intrinsic sizes (auto/max-content). Needed for
   smooth accordion + dropdown expand/collapse. Gracefully ignored where
   unsupported — fallback is simply the instant behavior you have today. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ── Base ────────────────────────────────────────────────── */

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font);
  font-size: var(--size-base);
  font-weight: var(--weight-regular);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--link);
  text-decoration: underline;
  text-decoration-color: var(--faint);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition:
    opacity var(--dur-fast) var(--ease),
    color   var(--dur-fast) var(--ease),
    text-decoration-color var(--dur-fast) var(--ease);
}

a:hover {
  opacity: 0.6;
}

/* ── Page enter/exit ─────────────────────────────────────── */
/* Only `.page` animates — the sidebar, gradient overlays and
   clock stay rock-solid at 100% opacity through navigations.
   JS (navbar.js) adds `.is-leaving` just before same-origin
   navigation; CSS handles the enter on every load. */

.page {
  animation: page-enter 280ms var(--ease) both;
}

@keyframes page-enter {
  from { filter: blur(8px); opacity: 0; }
  to   { filter: blur(0px); opacity: 1; }
}

.page.is-leaving {
  animation: page-exit 160ms var(--ease) forwards;
}

@keyframes page-exit {
  to { filter: blur(12px); opacity: 0; }
}

p {
  margin-bottom: 1rem;
}

hr {
  border: none;
  border-top: 1px solid var(--rule);
  margin: 2.5rem 0;
}

/* ── Page grid ───────────────────────────────────────────── */

.page {
  display: grid;
  grid-template-areas:
    "header"
    "main"
    "footer";
  grid-template-rows: auto 1fr auto;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 2.5rem 1.5rem 5rem;
  min-height: 100vh;
}

/* ── Sidebar nav ─────────────────────────────────────────── */

#site-nav {
  position: fixed;
  top: 2.5rem;
  left: calc(50vw - var(--max-width) / 2 - 224px);
  width: 168px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  visibility: hidden;
  z-index: 20;
}

/* ── Top fade overlay ────────────────────────────────────── */

body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 48px;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 1)    0%,
    rgba(255, 255, 255, 0.75) 15%,
    rgba(255, 255, 255, 0.45) 35%,
    rgba(255, 255, 255, 0.2)  55%,
    rgba(255, 255, 255, 0.08) 75%,
    rgba(255, 255, 255, 0.02) 90%,
    rgba(255, 255, 255, 0)    100%
  );
  pointer-events: none;
  z-index: 10;
}

body::after {
  content: '';
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 48px;
  background: linear-gradient(
    to top,
    rgba(255, 255, 255, 1)    0%,
    rgba(255, 255, 255, 0.75) 15%,
    rgba(255, 255, 255, 0.45) 35%,
    rgba(255, 255, 255, 0.2)  55%,
    rgba(255, 255, 255, 0.08) 75%,
    rgba(255, 255, 255, 0.02) 90%,
    rgba(255, 255, 255, 0)    100%
  );
  pointer-events: none;
  z-index: 10;
}

@media (min-width: 984px) {
  #site-nav {
    visibility: visible;
  }
}

.snav-logo {
  display: block;
  text-decoration: none;
  line-height: 0;
}

.snav-pfp {
  display: block;
  width: 36px;
  height: 36px;
  object-fit: cover;
  border-radius: var(--radius);
}

/* ── Top-level link list ─────────────────────────────────── */

.snav-links {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* Plain links: About, Contact */
.snav-links > a {
  font-size: var(--size-base);
  color: var(--muted);
  text-decoration: none;
  transition: color 0.12s;
}

.snav-links > a:hover,
.snav-links > a.is-active {
  color: var(--text);
  opacity: 1;
}

/* ── Group (Work / Play) ─────────────────────────────────── */

.snav-group {
  display: flex;
  flex-direction: column;
}

.snav-group-label {
  font-size: var(--size-base);
  color: var(--muted);
  text-decoration: none;
  transition: color 0.12s;
}

.snav-group-label:hover,
.snav-group.is-active .snav-group-label {
  color: var(--text);
  opacity: 1;
}

/* ── Sub-menu ─────────────────────────────────────────────── */
/* The submenu is always `display: flex` so it can animate open/closed
   via block-size + opacity. Margin-top collapses with it so closed
   submenus don't leave a ghost gap. `is-open` is toggled by navbar.js. */

.snav-submenu {
  display: flex;
  flex-direction: column;
  margin-top: 0;
  margin-left: 0;
  padding-left: 0;
  position: relative; /* positioning context for .snav-pill */

  block-size: 0;
  min-block-size: 0;
  opacity: 0;
  overflow: clip;
  pointer-events: none;
  transition:
    block-size var(--dur-base) var(--ease),
    margin-top var(--dur-base) var(--ease),
    opacity    var(--dur-base) var(--ease);
}

.snav-submenu.is-open {
  block-size: auto;
  margin-top: 0.35rem;
  opacity: 1;
  pointer-events: auto;
}

.snav-submenu a {
  display: block;
  font-size: var(--size-sm);
  color: var(--muted);
  text-decoration: none;
  line-height: 1.35;
  margin-left: 0.95rem;
  padding: 0.42rem 0.75rem;
  border-radius: var(--radius);
  white-space: nowrap;
  position: relative; /* sit above the pill */
  z-index: 1;
  transition: color var(--dur-fast) var(--ease);
}

.snav-submenu a:hover {
  color: var(--text);
  opacity: 1;
}

.snav-submenu a.is-active {
  color: var(--text);
  /* background is now rendered by the separate .snav-pill element
     so it can slide between items on navigation. */
}

/* Active-item "pill" — positioned and animated from navbar.js.
   Starts at the previous page's active link (via sessionStorage)
   and slides to the current one on the next frame, so the pill
   appears to persist across hard navigations. */
.snav-pill {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  background: var(--surface);
  border-radius: var(--radius);
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  transform: translate(0, 0);
  transition:
    transform var(--dur-base) var(--ease),
    width     var(--dur-base) var(--ease),
    height    var(--dur-base) var(--ease),
    opacity   var(--dur-fast) var(--ease);
  will-change: transform;
}

/* Overflow items animate in instead of popping. `display:none` can't
   transition, so we collapse via block-size + opacity. `min-block-size: 0`
   is required — flex items default to `min-height: auto`, which would
   otherwise keep them at their natural height and leave a ghost gap
   above the "See all work" button. */
.snav-submenu.is-truncated .snav-submenu-overflow {
  block-size: 0;
  min-block-size: 0;
  opacity: 0;
  overflow: clip;
  pointer-events: none;
  transition:
    block-size var(--dur-base) var(--ease),
    opacity    var(--dur-base) var(--ease);
}

.snav-submenu.is-truncated.is-expanded .snav-submenu-overflow {
  block-size: auto;
  opacity: 1;
  pointer-events: auto;
}

.snav-submenu-more {
  display: block;
  margin-left: 0.95rem;
  margin-top: 0.34rem;
  margin-bottom: 0.34rem;
  padding: 0.18rem 0.75rem;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 0.64rem;
  font-weight: var(--weight-subhead);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: inherit;
  line-height: 1.2;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition:
    color     var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.snav-submenu-more:hover {
  color: var(--text);
}

.snav-submenu-more:active {
  transform: scale(0.97);
}

.caption .snav-submenu-more {
  display: inline;
  margin: 0;
  padding: 0;
}

/* ── Project info panel (right) ─────────────────────────── */

.project-info {
  position: absolute;
  top: 2.5rem;
  right: calc(50vw - var(--max-width) / 2 - 224px);
  width: 168px;
  visibility: hidden;
  z-index: 20;
}

@media (min-width: 984px) {
  .project-info {
    visibility: visible;
  }
}

.project-info-card {
  background: var(--surface);
  border-radius: 10px;
  padding: 1rem 1.1rem;
}

.project-info-field {
  padding: 0.7rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.07);
}

.project-info-field:first-child {
  padding-top: 0;
}

.project-info-field:last-child {
  padding-bottom: 0;
  border-bottom: none;
}

.project-info-label {
  font-size: 0.6rem;
  font-weight: var(--weight-subhead);
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 0.25rem;
}

.project-info-value {
  font-size: var(--size-sm);
  line-height: 1.45;
  color: var(--text);
}

.project-info-link {
  margin-top: 7px;
  background: var(--surface);
  border-radius: 10px;
  padding: 0.8rem 1.1rem;
}

.project-info-link a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  text-decoration: none;
  color: var(--text);
  font-size: var(--size-sm);
  font-weight: var(--weight-subhead);
  line-height: 1.3;
  transition:
    opacity   var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

.project-info-link a:hover {
  opacity: 0.6;
}

.project-info-link a:active {
  transform: scale(0.99);
}

.project-info-link-arrow {
  font-size: 0.9rem;
  flex-shrink: 0;
  color: var(--muted);
}

/* ── Page header ─────────────────────────────────────────── */

.project-back {
  display: inline-block;
  font-size: var(--size-xs);
  color: var(--muted);
  text-decoration: none;
  margin-bottom: 0.75rem;
  transition: color 0.12s;
}

.project-back:hover {
  color: var(--text);
  opacity: 1;
}

.page-header {
  grid-area: header;
  margin-bottom: 2rem;
}

.page-header:has(.subtitle) {
  margin-bottom: 1.5rem;
}

/* Remove top gap from the first content element — img-full (and others)
   carry a margin-top designed for inter-section spacing, not page starts. */
.article > *:first-child {
  margin-top: 0;
}

.page-header h1 {
  font-size: var(--size-xl);
  font-weight: var(--weight-title);
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-bottom: 0.25rem;
}

.page-header .subtitle {
  font-size: var(--size-sm);
  color: var(--muted);
  margin-bottom: 0;
}

/* ── Main content ────────────────────────────────────────── */

.page-main {
  grid-area: main;
}

/* ── Footer ──────────────────────────────────────────────── */

.page-footer {
  grid-area: footer;
  font-size: var(--size-xs);
  color: var(--muted);
  padding-top: 3rem;
}

/* ── Headings (article) ──────────────────────────────────── */

.article h2 {
  font-size: var(--size-lg);
  font-weight: var(--weight-title);
  letter-spacing: -0.015em;
  margin-top: 2.5rem;
  margin-bottom: 0.6rem;
}

.article h3 {
  font-size: var(--size-sm);
  font-weight: var(--weight-subhead);
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-top: 2rem;
  margin-bottom: 0.5rem;
}

/* ── Article body lists ──────────────────────────────────── */

.article ul,
.article ol {
  padding-left: 1.4em;
  margin-top: 0.9rem;
  margin-bottom: 1.4rem;
}

.article ul {
  list-style: disc;
}

.article ol {
  list-style: decimal;
}

.article li {
  margin-bottom: 0.3rem;
  line-height: 1.6;
}

.article li:last-child {
  margin-bottom: 0;
}

/* ── Work index list ─────────────────────────────────────── */

.work-index {
  list-style: none;
  border-top: 1px solid var(--rule);
}

.work-index li {
  position: relative;
  border-bottom: 1px solid var(--rule);
}

.work-index a {
  display: block;
  text-decoration: none;
  color: var(--text);
}

.work-index a:hover {
  opacity: 1;
}

.work-index a:hover .work-title {
  opacity: 0.5;
}

.work-info {
  padding: 0.875rem 0;
  width: 50%;
}

.work-thumb {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 50%;
  overflow: hidden;
}

.work-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: opacity 0.15s;
}

.work-index a:hover .work-thumb img {
  opacity: 0.7;
}

.work-title {
  display: block;
  font-size: var(--size-base);
  font-weight: 500;
  transition: opacity 0.12s;
}

.work-meta {
  display: block;
  font-size: var(--size-xs);
  color: var(--muted);
  margin-top: 0.15rem;
}

.see-all {
  display: inline-block;
  margin-top: 1rem;
  font-size: var(--size-xs);
  color: var(--muted);
  text-decoration: none;
  transition: color 0.12s;
}

.see-all:hover {
  color: var(--text);
}

/* ── Work card grid ──────────────────────────────────────── */

.work-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
  align-items: start;
  margin-top: 1.5rem;
}

.work-col {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.work-card a {
  display: block;
  text-decoration: none;
  color: var(--text);
  opacity: 1;
  transition: opacity 0.15s;
}

.work-card a:hover {
  opacity: 0.7;
}

.work-card-thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
}

.work-card-thumb.tall {
  aspect-ratio: 1 / 1;
}

.work-card-thumb img,
.work-card-thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.play-gradient-thumb {
  background: linear-gradient(135deg, #8ec5fc 0%, #e0c3fc 40%, #fbc2eb 100%);
}


.work-card-caption {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.work-card-title {
  font-size: var(--size-base);
  font-weight: 500;
}

.work-card-year {
  font-size: var(--size-xs);
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
}

/* ── Writing list ────────────────────────────────────────── */

.writing-list {
  list-style: none;
  border-top: 1px solid var(--rule);
}

.writing-list li {
  border-bottom: 1px solid var(--rule);
}

.writing-list a {
  display: grid;
  grid-template-areas: "title date";
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 1rem;
  padding: 0.75rem 0;
  text-decoration: none;
  color: var(--text);
}

.writing-list a:hover .wl-title {
  opacity: 0.5;
}

.wl-title {
  grid-area: title;
  font-size: var(--size-base);
  font-weight: 400;
  transition: opacity 0.12s;
}

.wl-date {
  grid-area: date;
  font-size: var(--size-xs);
  color: var(--muted);
  white-space: nowrap;
}

/* ── Tags / chips ────────────────────────────────────────── */

.tag-row {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

.tag {
  font-size: var(--size-xs);
  color: var(--muted);
  border: 1px solid var(--rule);
  padding: 0.2em 0.6em;
  border-radius: var(--radius);
}

/* ── Aside / pull quote ──────────────────────────────────── */

.aside {
  border-left: 2px solid var(--rule);
  padding-left: 1rem;
  color: var(--muted);
  font-size: var(--size-sm);
  margin: 1.5rem 0;
}

/* ── Accordion / dropdown ────────────────────────────────── */

.accordion {
  margin: 1.5rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.accordion-item + .accordion-item {
  border-top: 1px solid var(--rule);
}

.accordion-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  cursor: pointer;
  list-style: none;
  font-size: var(--size-base);
  font-weight: var(--weight-regular);
  line-height: 1.45;
  padding: 0.95rem 0;
}

.accordion-summary::-webkit-details-marker {
  display: none;
}

/* Plus icon drawn as two thin bars so it can rotate smoothly
   to an × on open, rather than snapping between + and −. */
.accordion-summary::after {
  content: "";
  display: block;
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: var(--muted);
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat;
  transition: transform var(--dur-base) var(--ease);
}

.accordion-item[open] .accordion-summary::after {
  transform: rotate(45deg);
}

.accordion-panel {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  margin: 0 0 0.95rem;
}

.accordion-panel p {
  color: var(--muted);
  margin-bottom: 0.85rem;
}

.accordion-panel p:last-child {
  margin-bottom: 0;
}

.accordion-panel ol {
  margin: 0;
  padding-left: 1.2rem;
}

.accordion-panel li {
  color: var(--muted);
  margin-bottom: 0.35rem;
}

.accordion-panel li:last-child {
  margin-bottom: 0;
}

/* Smooth expand/collapse. Uses the native `::details-content` pseudo,
   which, combined with `interpolate-size: allow-keywords`, lets us
   transition to/from intrinsic height without measuring it in JS.
   Where unsupported (older browsers) the selector is ignored and
   <details> retains its native instant behavior. */
@supports (interpolate-size: allow-keywords) {
  .accordion-item::details-content {
    opacity: 0;
    block-size: 0;
    overflow: clip;
    transition:
      content-visibility var(--dur-slow) allow-discrete,
      opacity    var(--dur-base) var(--ease),
      block-size var(--dur-slow) var(--ease);
  }

  .accordion-item[open]::details-content {
    opacity: 1;
    block-size: auto;
  }
}

/* ── Code ────────────────────────────────────────────────── */

pre {
  background: var(--surface-dark);
  color: #e8e8e8;
  font-family: 'SF Mono', 'Fira Code', monospace;
  font-size: 0.75rem;
  line-height: 1.65;
  padding: 1.25rem;
  border-radius: var(--radius);
  overflow-x: auto;
  margin: 1.5rem 0;
}

code {
  font-family: 'SF Mono', 'Fira Code', monospace;
  font-size: var(--size-xs);
  background: var(--surface);
  padding: 0.1em 0.35em;
  border-radius: 3px;
}

pre code {
  background: none;
  padding: 0;
  font-size: inherit;
}

/* ── Footnotes ───────────────────────────────────────────── */

sup {
  font-size: 0.6rem;
  line-height: 0;
  vertical-align: super;
}

sup a { text-decoration: none; color: var(--muted); }

.footnotes {
  border-top: 1px solid var(--rule);
  padding-top: 1.25rem;
  margin-top: 3rem;
}

.footnotes h2 {
  font-size: var(--size-xs);
  font-weight: var(--weight-subhead);
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.footnotes ol {
  padding-left: 1.25rem;
}

.footnotes li {
  font-size: var(--size-sm);
  color: var(--muted);
  margin-bottom: 0.35rem;
}

/* ── Image caption ───────────────────────────────────────── */

.caption {
  font-size: var(--size-xs);
  font-weight: var(--weight-subtle);
  color: var(--muted);
  margin-top: 0.5rem;
  margin-bottom: 1.75rem;
}

/* Gradient generator: palette strip examples */
.gg-strip-stack {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 1rem 0 0;
}

.gg-strip {
  height: 3rem;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
}

.gg-strip.s1 {
  background: linear-gradient(96deg, #4458d0 0%, #7f46f2 30%, #e2c3ff 58%, #d3f2ff 100%);
}

.gg-strip.s2 {
  background: linear-gradient(90deg, #ff6b3d 0%, #f1d64d 33%, #81e8b2 64%, #64b5ff 100%);
}

.gg-strip.s3 {
  background: linear-gradient(102deg, #f3d8ff 0%, #c5b6ff 22%, #8fd4ff 47%, #9d7cff 74%, #f45ca6 100%);
}

.gg-strip.s4 {
  background: linear-gradient(88deg, #c5d0f7 0%, #ddbdf1 35%, #f08a5d 67%, #d4ef7a 100%);
}

.gg-click-image {
  display: block;
  width: 100%;
  margin-top: 1.2rem;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  padding: 0;
  cursor: pointer;
}

.gg-click-image img {
  display: block;
  width: 100%;
  border-radius: var(--radius);
}

/* ════════════════════════════════════════════════════════════
   CASE STUDY IMAGE GRIDS  —  all via CSS Grid Template Areas
   ════════════════════════════════════════════════════════════ */

/* ── Image cell base ─────────────────────────────────────── */
/* Apply .img-cell to any direct child of a grid layout.
   Add an aspect-ratio modifier class to control the shape.  */

.img-cell {
  overflow: hidden;
  background: var(--surface);
  border-radius: var(--radius);
}

.img-cell img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
}

/* Global no-crop image behavior: preserve full artwork.
   Layout blocks expand naturally to image height when needed. */
.img-cell:has(> img) {
  aspect-ratio: unset;
}

/* Hero banner: force 16:9 crop regardless of natural image dimensions */
.img-hero .img-cell:has(> img) {
  aspect-ratio: 16 / 9;
}

.img-hero .img-cell:has(> img) > img {
  height: 100%;
  object-fit: cover;
}

/* Portrait-trio: all cells lock to the correct iPhone ratio.
   Images and videos both fill with cover so outliers (e.g. wider
   environment screenshots) are cropped to match, not stretched. */
.img-portrait-trio .img-cell {
  aspect-ratio: 9 / 19.5;
}

.img-portrait-trio .img-cell > img,
.img-portrait-trio .img-cell > video {
  height: 100%;
  object-fit: cover;
}

/* Portrait-trio image cells stay locked to the iPhone ratio. */
.img-portrait-trio .img-cell:has(> img) {
  aspect-ratio: 9 / 19.5;
}

.img-portrait-trio .img-cell:has(> img) > img {
  height: 100%;
  object-fit: cover;
}

/* Videos in 2-col / asym / staggered: let the grid row height
   (set by the natural-sized sibling image) drive the cell height.
   The base rule already sets height: 100% on video elements. */
.img-2col .img-cell:has(> video),
.img-asym .img-cell:has(> video),
.img-staggered .img-cell:has(> video) {
  aspect-ratio: unset;
}

/* Aspect ratio modifiers */
.ar-wide      { aspect-ratio: 5 / 2;  }   /* hero / cinematic   */
.ar-landscape { aspect-ratio: 4 / 3;  }   /* standard landscape */
.ar-video     { aspect-ratio: 16 / 9; }   /* widescreen         */
.ar-square    { aspect-ratio: 1 / 1;  }   /* square             */
.ar-portrait  { aspect-ratio: 2 / 3;  }   /* tall portrait      */
.ar-tall      { aspect-ratio: 3 / 5;  }   /* very tall portrait */

/* Explicit no-crop class (same behavior as global default).
   Kept for readability on content-heavy sections. */
.img-cell.ar-natural {
  aspect-ratio: unset;
}

.img-cell.ar-natural > img {
  height: auto;
  object-fit: contain;
}


/* ── 1. Full-width ───────────────────────────────────────── */
.img-full {
  display: grid;
  grid-template-areas: "img";
  margin: 2rem 0 0;
}

.img-full > * { grid-area: img; }


/* ── 2. Equal 2-col ──────────────────────────────────────── */
.img-2col {
  display: grid;
  grid-template-areas: "left right";
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
  margin: 2rem 0 0;
}

.img-2col .col-left  { grid-area: left; }
.img-2col .col-right { grid-area: right; }


/* ── 3. Equal 3-col ──────────────────────────────────────── */
.img-3col {
  display: grid;
  grid-template-areas: "a b c";
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0.625rem;
  margin: 2rem 0 0;
}

.img-3col .col-a { grid-area: a; }
.img-3col .col-b { grid-area: b; }
.img-3col .col-c { grid-area: c; }


/* ── 4. Feature: wide left + 2 stacked right ─────────────── */
.img-feature {
  display: grid;
  grid-template-areas:
    "big top"
    "big bot";
  grid-template-columns: 3fr 2fr;
  grid-template-rows: 1fr 1fr;
  gap: var(--gap);
  margin: 2rem 0 0;
}

.img-feature .col-big { grid-area: big; }
.img-feature .col-top { grid-area: top; }
.img-feature .col-bot { grid-area: bot; }


/* ── 5. Vertical stack: 2 landscape images ───────────────── */
.img-stack {
  display: grid;
  grid-template-areas:
    "top"
    "bot";
  gap: var(--gap);
  margin: 2rem 0 0;
}

.img-stack .col-top { grid-area: top; }
.img-stack .col-bot { grid-area: bot; }


/* ── 6. Asymmetric: portrait left, landscape right ────────── */
/*    Good for showing a detail alongside a wider context.    */
.img-asym {
  display: grid;
  grid-template-areas: "portrait landscape";
  grid-template-columns: 2fr 3fr;
  gap: var(--gap);
  margin: 2rem 0 0;
  align-items: start;
}

.img-asym .col-portrait  { grid-area: portrait; }
.img-asym .col-landscape { grid-area: landscape; }


/* ── 7. Portrait trio: 3 tall images side by side ────────── */
/*    Great for mood boards and material studies.             */
.img-portrait-trio {
  display: grid;
  grid-template-areas: "p1 p2 p3";
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0.625rem;
  margin: 2rem 0 0;
}

.img-portrait-trio .col-p1 { grid-area: p1; }
.img-portrait-trio .col-p2 { grid-area: p2; }
.img-portrait-trio .col-p3 { grid-area: p3; }


/* ── 8. Staggered stack: wide + narrow side-by-side ──────── */
/*    Top row: single wide. Bottom row: two equal.            */
.img-staggered {
  display: grid;
  grid-template-areas:
    "wide wide"
    "sm1  sm2";
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
  margin: 2rem 0 0;
}

.img-staggered .col-wide { grid-area: wide; }
.img-staggered .col-sm1  { grid-area: sm1;  }
.img-staggered .col-sm2  { grid-area: sm2;  }


/* ── 9. Feature right: 2 stacked left + wide right ──────── */
/*    Mirror of img-feature — big image on the right.        */
.img-feature-right {
  display: grid;
  grid-template-areas:
    "top big"
    "bot big";
  grid-template-columns: 2fr 3fr;
  grid-template-rows: 1fr 1fr;
  gap: var(--gap);
  margin: 2rem 0 0;
}

.img-feature-right .col-big { grid-area: big; }
.img-feature-right .col-top { grid-area: top; }
.img-feature-right .col-bot { grid-area: bot; }


/* ── 10. Icon / asset grid ───────────────────────────────── */
/*    For large sets of small assets: icons, borders, tiles. */
.img-icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 0.375rem;
  margin: 2rem 0 0;
}

.img-icon-grid img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  background: var(--surface);
}

/* Trail effects grid — tall/narrow images, 5 per row, natural height */
.img-trail-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.625rem;
  margin: 2rem 0 0;
}

.img-trail-grid img {
  display: block;
  width: 100%;
  height: auto;
}


/* ── Video inside image cells ────────────────────────────── */
.img-cell video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Dark background modifier — for phone screens / dark mockups */
.bg-dark {
  background: #1a1a1a !important;
}

/* Full-width controlled video (e.g. hero films) */
.video-full {
  display: block;
  width: 100%;
  margin: 2rem 0 0;
  background: #000;
}

/* ── Vector stuff ─────────────────────────────────── */

.swatch-labels {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.25rem;
  margin-top: 0.5rem;
}

.swatch-label strong {
  display: block;
  font-size: var(--size-xs);
  font-weight: 500;
}

.swatch-label span {
  font-size: 0.62rem;
  color: var(--muted);
}


/* ── Responsive collapse ─────────────────────────────────── */
@media (max-width: 520px) {
  .img-2col {
    grid-template-areas: "left" "right";
    grid-template-columns: 1fr;
  }
  .img-3col {
    grid-template-areas: "a" "b" "c";
    grid-template-columns: 1fr;
  }
  .img-feature {
    grid-template-areas: "big" "top" "bot";
    grid-template-columns: 1fr;
  }
  .img-feature-right {
    grid-template-areas: "top" "bot" "big";
    grid-template-columns: 1fr;
  }
  .img-asym {
    grid-template-areas: "portrait" "landscape";
    grid-template-columns: 1fr;
  }
  .img-portrait-trio {
    grid-template-areas: "p1 p2" "p3 p3";
    grid-template-columns: 1fr 1fr;
  }
  .img-staggered {
    grid-template-areas: "wide" "sm1" "sm2";
    grid-template-columns: 1fr;
  }
  .work-thumb {
    display: none;
  }
  .work-grid {
    grid-template-columns: 1fr;
  }
}

/* ─── Button demo ─────────────────────────────────────────────── */

.btn-demo {
  background: #FAFAFA;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3rem;
  padding: 3.5rem 2rem;
  width: 100%;
  box-sizing: border-box;
}

.btn-demo-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.velo-btn {
  cursor: pointer;
  border: none;
  font-family: 'Fredoka One', Fredoka, sans-serif;
  font-size: 16px;
  font-weight: 500;
  padding: 0 40px;
  height: 52px;
  min-width: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.1s ease, transform 0.08s ease, box-shadow 0.1s ease;
  user-select: none;
  -webkit-user-select: none;
  outline: none;
}

.velo-btn--primary {
  background: #FFC700;
  border-radius: 10px;
  box-shadow: 0 3px 0 0 #FBAE17;
  color: #0C0C0C;
}
.velo-btn--primary:hover  { background: #FFE790; }
.velo-btn--primary:active { background: #D4970D; transform: translateY(2px); box-shadow: 0 1px 0 0 #FBAE17; }

.velo-btn--secondary {
  background: #FBFBFB;
  border-radius: 15px;
  box-shadow: 0 0 0 2px #B9B6B3, 0 4px 0 2px #B9B6B3;
  color: #0C0C0C;
}
.velo-btn--secondary:hover  { background: #F0F0F0; }
.velo-btn--secondary:active { background: #DCDCDC; transform: translateY(2px); box-shadow: 0 0 0 2px #B9B6B3, 0 2px 0 2px #B9B6B3; }

.velo-btn--accent {
  background: #FF7C33;
  border-radius: 25px;
  color: #fff;
}
.velo-btn--accent:hover  { background: #FFAE80; }
.velo-btn--accent:active { background: #CC5520; transform: translateY(2px); }

.btn-demo-spec {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
}

.btn-demo-name {
  font-size: 8px;
  letter-spacing: 1.5px;
  color: #AAAAAA;
  text-transform: uppercase;
}

/* ── About page ──────────────────────────────────────────── */

.about-image {
  margin-bottom: 2rem;
}

.about-image img {
  display: block;
  width: 100%;
}

.about-cta {
  color: #e95124;
}

/* ── Contact page ────────────────────────────────────────── */

.contact-intro {
  color: var(--text);
  max-width: 52ch;
}

.contact-actions {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-top: 1.1rem;
}

.contact-actions .url-button {
  margin-top: 0;
}

.contact-actions .url-button--split {
  display: grid;
  grid-template-columns: 88px 1px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0.85rem;
}

.contact-actions .url-button-main {
  font-size: var(--size-base);
  font-weight: var(--weight-subhead);
  line-height: 1.3;
}

.contact-actions .url-button-divider {
  width: 1px;
  height: 1.2rem;
  background: var(--rule);
}

.contact-actions .url-button-meta {
  font-size: var(--size-sm);
  color: var(--muted);
  line-height: 1.35;
  min-width: 0;
}

/* ── Footer links ────────────────────────────────────────── */

.page-footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.page-footer-links {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
}

.page-footer-links a {
  font-size: var(--size-xs);
  color: var(--muted);
  text-decoration: none;
}

.page-footer-links a:hover {
  color: var(--text);
  opacity: 1;
}

.page-footer-links .divider {
  font-size: var(--size-xs);
  color: var(--faint);
}

/* ── External URL button ─────────────────────────────────── */

.url-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  width: 100%;
  margin-top: 1rem;
  padding: 0.82rem 1rem;
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius) + 5px);
  background: transparent;
  color: var(--text);
  text-decoration: none;
  transition:
    background   var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    transform    var(--dur-fast) var(--ease);
}

.url-button:hover {
  background: var(--surface);
  border-color: var(--surface);
  opacity: 1;
}

.url-button:active {
  transform: scale(0.99);
}

.url-button-left {
  display: flex;
  align-items: center;
  gap: 0;
  min-width: 0;
}

.url-button-text {
  font-size: var(--size-base);
  font-weight: var(--weight-subhead);
  line-height: 1.35;
}

.url-button-arrow {
  color: var(--text);
  font-size: 1.02rem;
  line-height: 1;
  flex-shrink: 0;
}

.btn-demo-state {
  font-size: 8px;
  letter-spacing: 1.5px;
  color: #CCCCCC;
  text-transform: uppercase;
  min-width: 60px;
  text-align: center;
}

/* ── Index hero video ────────────────────────────────────── */

.hero-video {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  border-radius: var(--radius);
  object-fit: cover;
}
