/* ==========================================================================
   Kriel Ventures
   A centred deco opening on black, then the four crafts as four squares.
   Type does the work; one warm accent is the only ornament.
   ========================================================================== */

/* --- Stadium -------------------------------------------------------------
   Stadium by Matthew Welch (squaregear.net), MIT licence — see
   fonts/stadium-license.txt, which ships with the site as the licence
   requires. One weight, no italic: never ask for bold or italic anywhere or
   the browser will synthesise it and smear these geometric letterforms.
   ------------------------------------------------------------------------ */
@font-face {
  font-family: "Stadium";
  src: url("fonts/stadium.woff2") format("woff2"),
       url("fonts/stadium.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* --- Tokens --------------------------------------------------------------- */
:root {
  --ink:        #0B0B0B;
  --ink-soft:   #7C7C7C;
  --bone:       #F2EFE8;
  --chip:       #F4F2ED;

  /* one accent per square */
  --blue:       #2438F0;
  --blush:      #F9B6BE;
  --red:        #EE3B24;
  --cream:      #F4F1EA;

  /* the warm accent, and the light it throws */
  --tan:        #D9B183;

  --display: "Stadium", "Futura", "Century Gothic", "Avenir Next", sans-serif;
  --ui:      "Space Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;

  --edge:   clamp(1.5rem, 2.4vw, 2.25rem);
  --gutter: clamp(0.55rem, 1.3vw, 1.15rem);

  --ease: cubic-bezier(0.22, 0.68, 0.24, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--ui);
  font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.0625rem);
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; }
a   { color: inherit; }
h1, h2, h3, p, ul, ol { margin: 0; }
ul, ol { list-style: none; padding: 0; }

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

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Focus ---------------------------------------------------------------- */
:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 4px;
  border-radius: 2px;
}

.skip-link {
  position: fixed;
  top: 0; left: 0;
  z-index: 200;
  transform: translateY(-120%);
  background: var(--bone);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 400;
  font-size: 1rem;
  letter-spacing: 0.02em;
  padding: 0.85rem 1.25rem;
  text-decoration: none;
}
.skip-link:focus-visible { transform: translateY(0); }

/* --- Reveals -------------------------------------------------------------
   .rise clips its inner span and slides it up. The clip box is padded below
   so descenders (the g in Photography, Videography) aren't shaved off — the
   negative margin cancels the padding so layout is unchanged.
   ------------------------------------------------------------------------ */
.rise {
  display: block;
  overflow: hidden;
  padding-bottom: 0.18em;
  margin-bottom: -0.18em;
}
.rise > span { display: block; }
/* 130%, not 105% — the clip box is now taller than the span by the descender
   padding, so a smaller offset leaves a hairline of letter-tops showing. */
.js .rise > span {
  transform: translateY(130%);
  transition: transform 0.95s var(--ease);
}
.js .is-in .rise > span { transform: translateY(0); }
.js .is-in .rise:nth-child(2) > span { transition-delay: 0.09s; }

/* .lift is the unclipped variant, for a line whose glow has to spill past
   its own box. */
.lift { display: block; }
.js .lift {
  opacity: 0;
  transform: translateY(0.4em);
  transition: opacity 0.9s var(--ease) 0.26s, transform 0.9s var(--ease) 0.26s;
}
.js .is-in .lift { opacity: 1; transform: none; }

/* ==========================================================================
   Menu
   ========================================================================== */
.menu-btn {
  position: fixed;
  top: clamp(0.85rem, 1.3vw, 1.15rem);
  right: clamp(0.85rem, 1.3vw, 1.15rem);
  z-index: 120;

  min-height: 46px;
  min-width: 92px;
  padding: 0.6rem 1.4rem;

  background: var(--chip);
  color: var(--ink);
  border: 0;
  border-radius: 10px;
  cursor: pointer;

  /* Deliberately not Stadium: the two fixed controls at the top of the screen
     stay in the grotesque, so the deco face reads as the voice of the page
     rather than the chrome around it. */
  font-family: var(--ui);
  font-weight: 700;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.35rem);
  letter-spacing: -0.02em;

  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.menu-btn:hover { background: #fff; }
.menu-btn[aria-expanded="true"] { background: var(--bone); }

.menu {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: var(--ink);
  display: grid;
  padding: clamp(1.5rem, 3vw, 3rem) var(--edge) clamp(1.75rem, 3vw, 3rem);
  overflow-y: auto;
}
.menu[hidden] { display: none; }

.menu__inner {
  display: grid;
  align-content: space-between;
  gap: 2rem;
}

.menu__eyebrow {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  color: var(--ink-soft);
}

.menu__list { display: grid; gap: clamp(0.15rem, 0.6vh, 0.5rem); }

.menu__list a {
  display: flex;
  align-items: baseline;
  gap: clamp(0.75rem, 2vw, 2rem);
  padding: 0.12em 0;
  text-decoration: none;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.9rem, 6.6vw, 4.5rem);
  line-height: 1.18;
  letter-spacing: 0.015em;
  color: var(--bone);
  transition: color 0.2s var(--ease);
}
.menu__list a:hover { color: var(--tan); }

.menu__num {
  font-family: var(--ui);
  font-size: clamp(0.7rem, 1.1vw, 0.9rem);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  flex: none;
  min-width: 1.75em;
}

.menu__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  font-family: var(--ui);
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.menu__foot a { text-decoration: none; }
.menu__foot a:hover { color: var(--bone); }

body.menu-open { overflow: hidden; }

/* ==========================================================================
   Opening
   ========================================================================== */
.opening {
  min-height: 78svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 2rem;
  padding: clamp(1.5rem, 2.6vw, 2.4rem) var(--edge) clamp(2.5rem, 6vh, 4.5rem);
  background: var(--ink);
}

.opening__mark {
  font-family: var(--ui);
  font-weight: 700;
  font-size: clamp(0.85rem, 0.78rem + 0.3vw, 1.05rem);
  letter-spacing: -0.012em;
  color: var(--bone);
}
.opening__mark a { text-decoration: none; }

.opening__line {
  align-self: center;
  justify-self: center;
  text-align: center;
  max-width: 22ch;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.5rem, 0.9rem + 7.4vw, 8.5rem);
  line-height: 1.16;
  letter-spacing: 0.012em;
  color: var(--bone);
}

/* Soft spotlight: a pool of warm light behind the word, not a glow traced
   round the letters. It sits behind the type and spills well past the line,
   which is why this line uses .lift rather than the clipping .rise. */
.glow {
  position: relative;
  display: inline-block;
  isolation: isolate;
}
.glow::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 52%;
  width: 132%;
  height: 210%;
  transform: translate(-50%, -50%);
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at center,
    rgba(255, 236, 208, 0.34) 0%,
    rgba(240, 200, 148, 0.19) 30%,
    rgba(217, 177, 131, 0.06) 52%,
    rgba(217, 177, 131, 0) 70%);
  filter: blur(22px);
}
.opening__line em {
  font-style: normal;   /* Stadium has no italic — never synthesise one */
  color: var(--tan);
}

.opening__sub {
  justify-self: center;
  text-align: center;
  max-width: 42ch;
  font-family: var(--ui);
  font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.15rem);
  color: var(--ink-soft);
}

/* ==========================================================================
   The four squares
   ========================================================================== */
.panes {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gutter);
  padding: 0 var(--edge) var(--edge);
  background: var(--ink);
}

/* Grid rather than an absolutely positioned text block: the text has to be a
   static descendant so the stretched link inside it resolves against the
   square, not against the text block. */
.pane {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: 1fr auto;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #0d0b09;
}

.pane__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  transition: transform 0.9s var(--ease);
}
.pane:hover .pane__img { transform: scale(1.035); }

/* Object positions chosen per photograph so the square crop keeps its subject. */
.pane[data-key="photography"] .pane__img { object-position: 42% 60%; }
.pane[data-key="videography"] .pane__img { object-position: 46% 50%; }
.pane[data-key="web"]         .pane__img { object-position: 55% 50%; }
.pane[data-key="audio"]       .pane__img { object-position: 52% 50%; }

/* Each square is washed the direction its own photograph runs: the three dark
   ones deepen at the foot, the misty one fogs up pale so the blue holds. */
.pane__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(198deg, rgba(255,255,255,0.055) 0%, rgba(255,255,255,0) 42%),
    linear-gradient(180deg, rgba(0,0,0,0.22) 0%, rgba(0,0,0,0.08) 34%, rgba(0,0,0,0.55) 74%, rgba(0,0,0,0.82) 100%);
}

.pane[data-key="videography"] .pane__scrim {
  background:
    linear-gradient(198deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0) 42%),
    linear-gradient(180deg, rgba(0,0,0,0.26) 0%, rgba(0,0,0,0.12) 30%, rgba(0,0,0,0.68) 70%, rgba(0,0,0,0.88) 100%);
}

.pane[data-key="photography"] .pane__scrim {
  background:
    linear-gradient(198deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0) 42%),
    linear-gradient(180deg, rgba(233,235,238,0.10) 0%, rgba(233,235,238,0.08) 34%, rgba(238,238,233,0.66) 62%, rgba(240,239,233,0.94) 100%);
}

.pane__text {
  grid-row: 2;
  padding: clamp(1.1rem, 2.2vw, 2rem);
}

.pane__label {
  font-family: var(--ui);
  font-weight: 700;
  font-size: clamp(0.78rem, 0.72rem + 0.22vw, 0.95rem);
  line-height: 1.3;
  letter-spacing: -0.012em;
  color: var(--accent);
  margin-bottom: 0.3em;
}
.pane__label span { display: block; }

.pane__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.85rem, 0.85rem + 4vw, 3.9rem);
  line-height: 1.04;
  letter-spacing: 0.012em;
  color: var(--accent);
}

/* The title is the link, but the whole square is the target — the ::after
   stretches over the pane so there's no small tap area on a phone.
   The <a> must wrap .rise rather than sit inside it: .rise has overflow
   hidden, and an ancestor with overflow between an absolute box and its
   containing block clips that box to the line. */
.pane__title a {
  display: block;
  text-decoration: none;
  color: inherit;
}
.pane__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
}
.pane__title a:focus-visible { outline-offset: 6px; }

.pane__note {
  max-width: 32ch;
  margin-top: 0.7rem;
  font-family: var(--ui);
  font-weight: 500;
  font-size: clamp(0.85rem, 0.8rem + 0.18vw, 0.98rem);
  line-height: 1.45;
  color: var(--accent);
}
.js .pane__note {
  opacity: 0;
  transform: translateY(0.6rem);
  transition: opacity 0.7s var(--ease) 0.3s, transform 0.7s var(--ease) 0.3s;
}
.js .pane.is-in .pane__note { opacity: 0.9; transform: none; }

/* One accent per service, shared by its square and its own page. */
[data-key="photography"] { --accent: var(--blue); }
[data-key="videography"] { --accent: var(--blush); }
[data-key="web"]         { --accent: var(--red); }
[data-key="audio"]       { --accent: var(--cream); }

/* ==========================================================================
   Service holding pages
   Temporary. When a real service page is built it takes the site's full
   chrome; until then these are deliberately a stub.
   ========================================================================== */
.holding {
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 2rem;
  padding: clamp(1.5rem, 2.6vw, 2.4rem) var(--edge) clamp(2rem, 5vh, 3.5rem);
  background: var(--ink);
}

/* No measure on the wrapper — a ch-based cap here would crop the title,
   which .rise then clips (PHOTOGRAPHY became PHOTOGR). The measure belongs
   on the prose underneath. */
.holding__body { align-self: center; }

.holding__label {
  font-family: var(--ui);
  font-weight: 700;
  font-size: clamp(0.85rem, 0.78rem + 0.3vw, 1.05rem);
  line-height: 1.3;
  letter-spacing: -0.012em;
  color: var(--accent);
  margin-bottom: 0.35em;
}
.holding__label span { display: block; }

.holding__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.4rem, 1rem + 6.4vw, 7rem);
  line-height: 1.06;
  letter-spacing: 0.012em;
  color: var(--accent);
}

.holding__rule {
  height: 1px;
  border: 0;
  max-width: 46ch;
  margin: clamp(1.75rem, 4vh, 2.75rem) 0 clamp(1.25rem, 3vh, 1.75rem);
  background: currentColor;
  color: var(--accent);
  opacity: 0.4;
}

.holding__state {
  font-family: var(--ui);
  font-weight: 700;
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.5rem);
  letter-spacing: -0.015em;
  color: var(--bone);
  margin-bottom: 0.5em;
}

.holding__note {
  max-width: 46ch;
  font-family: var(--ui);
  font-weight: 500;
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.1rem);
  color: var(--ink-soft);
}
.holding__note a { color: var(--bone); text-decoration: none; }
.holding__note a:hover { text-decoration: underline; text-underline-offset: 3px; }

.holding__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  font-family: var(--ui);
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.holding__foot a { text-decoration: none; }
.holding__foot a:hover { color: var(--bone); }

@media (max-width: 719px) {
  .holding__foot a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* ==========================================================================
   Footer
   ========================================================================== */
.footer {
  background: var(--ink);
  color: var(--bone);
  padding: clamp(3rem, 9vh, 6.5rem) var(--edge) clamp(1.5rem, 4vh, 2.5rem);
  font-family: var(--ui);
  font-weight: 500;
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.2rem);
  line-height: 1.5;
}

.footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.25rem, 5vw, 4rem);
}

.footer__head {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.05rem, 1rem + 0.35vw, 1.35rem);
  letter-spacing: 0.06em;
  margin-bottom: 1.1em;
}
.footer__block + .footer__block { margin-top: 1.25em; }
.footer__list li + li { margin-top: 0.1em; }
.footer a { text-decoration: none; }
.footer a:hover { text-decoration: underline; text-underline-offset: 3px; }

.muted, .footer__list--muted a { color: var(--ink-soft); }
.footer__list--muted a:hover { color: var(--bone); }

/* A channel that doesn't exist yet: it holds its place in the list, but as
   plain text with a status beside it rather than a link going nowhere. The
   status is set smaller rather than dimmer — dimmer would drop it under the
   4.5:1 it needs at this size. */
.footer__soon {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  color: var(--ink-soft);
}
.footer__soon-note {
  font-size: 0.76em;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.footer__soon-note::before {
  content: "";
  display: inline-block;
  width: 1.1em;
  height: 1px;
  margin-right: 0.55em;
  vertical-align: middle;
  background: currentColor;
  opacity: 0.6;
}

/* Touch targets: the tight footer stack is right on a pointer device, but
   needs real height under a thumb. */
@media (max-width: 719px) {
  .footer__list a,
  .footer__base a,
  .menu__foot a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .footer__list li + li { margin-top: 0; }
  /* Not a target, but it keeps the row rhythm of the links around it. */
  .footer__soon { min-height: 44px; align-items: center; }
}

.footer__base {
  display: flex;
  justify-content: space-between;
  gap: 1rem 2rem;
  flex-wrap: wrap;
  margin-top: clamp(3rem, 10vh, 7rem);
  font-family: var(--ui);
  font-weight: 500;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/* ==========================================================================
   Wider screens
   ========================================================================== */
@media (min-width: 760px) {
  .panes { grid-template-columns: 1fr 1fr; }
  .footer__grid { grid-template-columns: 2fr 1fr 1fr; }
}

@media (min-width: 1100px) {
  .footer__grid { grid-template-columns: 1.5fr 1fr 1fr 0.7fr; }
}

/* Past roughly 1500px a square gets taller than the screen, so the block
   stops growing and centres instead. */
@media (min-width: 1500px) {
  .panes {
    max-width: 1500px;
    margin-inline: auto;
  }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .rise > span,
  .js .lift,
  .js .pane__note {
    transform: none !important;
    opacity: 1;
    transition: none;
  }
  .js .pane.is-in .pane__note { opacity: 0.9; }
  .pane:hover .pane__img { transform: none; }
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
