/* Fonts are hosted here rather than loaded from Google, so visitors'
   browsers never contact Google (and never hand it their IP address).
   Both are SIL Open Font License. Files in fonts/, fetched from Google
   Fonts on 2026-09-11: latin and latin-ext only; the browser fetches
   latin-ext only if a page uses a character from it. Hanken Grotesk
   is one variable file covering 300-800.

   The URLs go through folio.php, which serves fonts without the
   password (the holding screen needs them) and caches them for a year:
   give a changed font file a new name. */

@font-face{
  font-family:'Hanken Grotesk';
  font-style:normal;
  font-weight:300 800;
  font-display:swap;
  src:url("folio.php?p=fonts/hanken-grotesk-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face{
  font-family:'Hanken Grotesk';
  font-style:normal;
  font-weight:300 800;
  font-display:swap;
  src:url("folio.php?p=fonts/hanken-grotesk-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face{
  font-family:'Inter';
  font-style:italic;
  font-weight:400;
  font-display:swap;
  src:url("folio.php?p=fonts/inter-italic-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face{
  font-family:'Inter';
  font-style:italic;
  font-weight:400;
  font-display:swap;
  src:url("folio.php?p=fonts/inter-italic-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url("folio.php?p=fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url("folio.php?p=fonts/inter-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root{
  /* Type scale */
  --fs-xl:52px;             --lh-xl:54px;
  --fs-h1-custom:40px;      --lh-h1-custom:56px;
  --fs-h1:32px;             --lh-h1:40px;
  --fs-h2:24px;             --lh-h2:36px;
  --fs-h3:20px;             --lh-h3:28px;
  --fs-h4:16px;             --lh-h4:24px;
  --fs-body:16px;           --lh-body:24px;
  --fs-body-long:16px;      --lh-body-long:16px;
  --fs-body-s:14px;         --lh-body-s:16px;
  --fs-body-xs:12px;        --lh-body-xs:14px;
  --fs-body-highlight:16px; --lh-body-highlight:24px;

  /* Color scale */
  --black-100:rgba(0,0,0,1);
  --black-80:rgba(0,0,0,0.8);
  --black-60:rgba(0,0,0,0.6);
  --black-40:rgba(0,0,0,0.4);
  --black-20:rgba(0,0,0,0.2);
  --black-10:rgba(0,0,0,0.1);
  --black-5:rgba(0,0,0,0.05);
  --white:#ffffff;

  --text-dark:var(--black-100);
  --text-body:var(--black-80);
  --text-muted:var(--black-40);
  /* Figma's ink for homepage text. The black tokens above stay as they
     are because the case studies still read them. */
  --ink:#424242;
  --link-color:#005d81;
  --rule-color:#e6e6e6;
  --bg:#ffffff;

  /* Layout grid: columns / margin / gutter per breakpoint */
  --grid-margin:20px;
  --grid-gutter:20px;
  --grid-columns:4;

  /* Derived: actual column width, and a "span 2 columns" tile size,
     both in real pixels (not % of a shrinkable parent) so tiles keep
     a fixed size and wrap instead of rescaling when siblings compete
     for row space. Based on container query units (not vw) so a
     scrollbar eating into the viewport doesn't throw the math off. */
  --content-width: calc(100cqw - 2 * var(--grid-margin));
  --col-width: calc((var(--content-width) - (var(--grid-columns) - 1) * var(--grid-gutter)) / var(--grid-columns));
  --tile-width: calc(var(--col-width) * 2 + var(--grid-gutter));
}

*{ box-sizing:border-box; }

body{
  margin:0;
  background:var(--bg);
  color:var(--text-dark);
  container-type:inline-size;
  font-family:'Hanken Grotesk', 'Century Gothic', sans-serif;
  -webkit-font-smoothing:antialiased;
}

.page{
  /* Only the top offset changes per breakpoint (where content starts).
     Every other vertical gap on the page stays constant everywhere. */
  padding:32px var(--grid-margin) 16px;
  display:flex;
  flex-direction:column;
  min-height:100vh;
  min-height:100dvh;
}

/* Grows to fill any leftover vertical space, pinning the footer to the
   bottom of the viewport when content is shorter than it. Has no effect
   when content is already taller than the viewport — it just flows. */
.folio{
  flex:1 0 auto;
}

h1, h2, h3{
  margin:0;
  font-weight:800;
  color:var(--text-dark);
}

p{
  margin:0 0 20px;
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  font-weight:500;
  color:var(--text-body);
}

a{
  text-decoration:none;
}

hr{
  border:none;
  border-top:1px solid var(--rule-color);
  margin:16px 0 32px;
}

/* ---------- Hero (name / title / about) ---------- */

.hero{
  display:grid;
  grid-template-columns:1fr;
  row-gap:32px;
  margin-bottom:24px;
}

/* XL — the name, on the homepage and the holding screen alike */
.hero-left h1,
.holding-intro h1{
  font-size:var(--fs-xl);
  line-height:var(--lh-xl);
  color:var(--ink);
  margin-bottom:16px;
}

/* Figma sets the name as two paragraphs with 8px between them. */
.hero-left h1 span,
.holding-intro h1 span{ display:block; }
.hero-left h1 span:first-child,
.holding-intro h1 span:first-child{ margin-bottom:8px; }

/* H1 */
.hero-left .subtitle,
.holding-intro .subtitle{
  font-size:var(--fs-h1);
  line-height:var(--lh-h1);
  font-weight:500;
  letter-spacing:-0.64px;
  color:var(--ink);
  margin:0;
}

/* H1 */
.hero-right h2{
  font-size:var(--fs-h1);
  line-height:var(--lh-h1);
  font-weight:500;
  letter-spacing:-0.64px;
  color:var(--ink);
  margin-bottom:16px;
}

/* H3 */
.hero-right p{
  font-size:var(--fs-h3);
  line-height:var(--lh-h3);
  letter-spacing:-0.4px;
  color:var(--ink);
  margin-bottom:8px;
}

.hero-right p:last-child{
  margin-bottom:0;
}

/* ---------- Folio section ---------- */

/* H1 */
.folio-title{
  font-size:var(--fs-h1);
  line-height:var(--lh-h1);
  font-weight:500;
  letter-spacing:-0.64px;
  color:var(--ink);
  margin-bottom:0;
}

/* Figma draws its 1px line above the line's position, so it reads 16px
   under the title and 32px over the content below. An hr draws below
   its top edge, hence 15 on top, not 16. */
.folio > hr{
  margin:15px 0 32px;
  border-top-color:#dfdfdf;
}

.folio-grid{
  display:grid;
  grid-template-columns:1fr;
  row-gap:32px;
}

/* H2 */
.projects h3,
.process h3{
  font-size:var(--fs-h2);
  line-height:var(--lh-h2);
  color:var(--ink);
  margin-bottom:20px;
}

.project-cards{
  display:flex;
  flex-wrap:wrap;
  gap:var(--grid-gutter);
  margin-bottom:20px;
}

.project-card{
  display:flex;
  flex-direction:column;
  flex:0 0 auto;
  gap:12px;
  /* Fixed px width (2 grid columns), independent of the parent's own
     width — so tiles wrap onto new rows instead of shrinking when
     more of them are added. */
  width:var(--tile-width);
}

.thumb{
  position:relative;
  width:100%;
  /* Padding hack for Figma's 190×186 tile: percentage padding is always
     relative to width, so this holds the ratio in every browser without
     depending on `aspect-ratio` support/timing like an earlier version. */
  height:0;
  padding-bottom:calc(186 / 190 * 100%);
  border-radius:8px;
  /* Set per-tile via style="--tile-gradient: ..." — see index.html */
  background:var(--tile-gradient, #e6e6e6);
}

/* 32px of padding inside the 190×186 tile, leaving a 126×122 box for
   the logo, all expressed as percentages so it scales with the tile. */
.thumb img{
  position:absolute;
  top:calc(32 / 186 * 100%);
  left:calc(32 / 190 * 100%);
  width:calc(126 / 190 * 100%);
  height:calc(122 / 186 * 100%);
  object-fit:contain;
}

/* H4 */
.project-label{
  font-size:var(--fs-h4);
  line-height:var(--lh-h4);
  font-weight:700;
  color:var(--link-color);
}

.more-soon{
  font-size:var(--fs-h3);
  line-height:var(--lh-h3);
  font-weight:500;
  letter-spacing:-0.4px;
  color:var(--text-muted);
  margin-bottom:0;
}

.process-group{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:8px;
}

.process-group + .process-group{ margin-top:20px; }
.process-group-links{ gap:16px; }

/* H3 type on an h4 element — it's a subheading under "Processes". */
.process-group h4{
  margin:0;
  font-size:var(--fs-h3);
  line-height:var(--lh-h3);
  font-weight:500;
  letter-spacing:-0.4px;
  color:var(--ink);
}

.process-body{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:16px;
  max-width:400px;
}

/* Body — Figma sets this style in Inter, not Hanken Grotesk. */
.process-body p{
  margin:0;
  font-family:'Inter', system-ui, sans-serif;
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  font-weight:400;
  color:var(--ink);
}

.process-links{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:8px;
}

/* Block, so the link's own 24px line box sets the row height instead of
   sitting on the list item's default one. */
.process-links a{ display:block; }

/* H4 */
.link{
  color:var(--link-color);
  font-weight:700;
  font-size:var(--fs-h4);
  line-height:var(--lh-h4);
}

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

footer{
  margin-top:0;
}

/* Homepage footer. Kept apart from the shared .footer-row/.brand rules
   below, which the case-study footers still use. */
.site-footer hr{
  /* Full bleed, edge to edge of the viewport, rather than the content
     width. cqw (not vw) so a scrollbar doesn't cause horizontal overflow. */
  width:100cqw;
  /* 47, not 48 — same 1px line offset as the Folio rule. */
  margin:47px 0 16px calc(50% - 50cqw);
  border-top-color:#d5d5d5;
}

.site-footer-row{
  display:flex;
  flex-direction:column;
  gap:6px;
  color:var(--ink);
  font-size:var(--fs-h4);
  line-height:var(--lh-h4);
}

/* H4 */
.site-footer-brand{ font-weight:700; }

/* Body */
.site-footer-year{
  font-family:'Inter', system-ui, sans-serif;
  font-weight:400;
}

.footer-row{
  display:flex;
  flex-direction:column;
  gap:6px;
  font-size:var(--fs-body-s);
  line-height:var(--lh-body-s);
}

.footer-row .brand{
  font-weight:700;
  color:var(--black-100);
}

.footer-row a{
  color:var(--black-80);
}

/* ---------- Holding screen (public/index.php) ---------- */

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

/* Takes up the slack so the footer sits at the bottom of the viewport. */
.holding-intro{ flex:1 0 auto; }

/* H3 */
.holding-blurb{
  max-width:505px;
  margin:16px 0 0;
  font-size:var(--fs-h3);
  line-height:var(--lh-h3);
  letter-spacing:-0.4px;
  color:var(--ink);
}

.entry{
  display:flex;
  flex-direction:column;
  gap:18px;
  width:205px;
  max-width:100%;
  margin-top:48px;
}

.entry-field{
  display:flex;
  flex-direction:column;
  gap:8px;
}

/* Empty state: the field waits until the button is pressed (set by JS). */
.entry.is-collapsed .entry-field{ display:none; }

/* Filled: Body, black. The native dot mask is what Figma shows. */
.entry-input{
  box-sizing:border-box;
  width:100%;
  height:54px;
  margin:0;
  padding:12px 32px 12px 12px;
  border:1px solid #333;
  border-radius:0;
  background:var(--white);
  font-family:'Inter', system-ui, sans-serif;
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  font-style:normal;
  font-weight:400;
  color:var(--black-100);
  outline:none;
  -webkit-appearance:none;
  appearance:none;
}

/* Opened: italic grey placeholder. Firefox fades placeholders by default. */
.entry-input::placeholder{
  font-style:italic;
  color:#666;
  opacity:1;
}

/* Figma's focus treatment is a soft glow, drawn only in the Filled state:
   focused and with something typed. Opened (still empty) and Error have
   none; the caret shows where the focus is. */
.entry-input:focus:not(:placeholder-shown){
  box-shadow:0 0 3px rgba(0, 93, 129, .5);
}

/* Error: the attempt turns red, and the glow goes until they edit it */
.entry.is-error .entry-input{
  color:#cd0000;
  box-shadow:none;
}

/* Body S */
.entry-error{
  margin:0;
  padding-left:12px;
  font-family:'Inter', system-ui, sans-serif;
  font-size:var(--fs-body-s);
  line-height:var(--lh-body-s);
  font-weight:400;
  color:#cd0000;
}

.entry-error[hidden]{ display:none; }

/* Cookie note: Body XS in grey beside the info icon. Hidden in the Empty
   state, like the field. Figma spaces it 16px from the button in Opened
   but 18px in Filled and Error; 18 throughout, so nothing shifts when
   typing starts. */
.entry-note{
  display:flex;
  align-items:flex-start;
  gap:4px;
  margin:0;
  font-family:'Inter', system-ui, sans-serif;
  font-size:var(--fs-body-xs);
  line-height:var(--lh-body-xs);
  font-weight:400;
  color:#666;
}

.entry-note svg{
  flex:0 0 20px;
  width:20px;
  height:20px;
}

.entry.is-collapsed .entry-note{ display:none; }

/* H3 label in an outlined box. Also used as a link when already signed in. */
.entry-button{
  box-sizing:border-box;
  display:flex;
  align-items:center;
  justify-content:center;
  width:100%;
  margin:0;
  padding:12px 32px;
  border:1px solid #333;
  border-radius:0;
  background:transparent;
  font-family:inherit;
  font-size:var(--fs-h3);
  line-height:var(--lh-h3);
  font-weight:500;
  letter-spacing:-0.4px;
  color:#333;
  /* The label is a touch wider than the 141px left inside the padding;
     Figma keeps it on one line too. */
  white-space:nowrap;
  cursor:pointer;
}

/* Used: solid fill, white label. Shown while pressed, while the password
   is being checked (disabled), on keyboard focus, and on hover where the
   device has one (on touch screens hover would stick after a tap). */
.entry-button:active,
.entry-button:disabled,
.entry-button:focus-visible{
  background:#333;
  color:var(--white);
  outline:none;
}

@media (hover:hover){
  .entry-button:hover{
    background:#333;
    color:var(--white);
  }
}

.entry-button:disabled{ cursor:progress; }

/* Rule across the content width, 16px above centred Body S. Figma draws
   its 1px line above the line's position, hence the border sits on top. */
.holding-footer{
  margin-top:48px;
  padding-top:16px;
  border-top:1px solid #d5d5d5;
}

.holding-footer p{
  margin:0;
  text-align:center;
  font-family:'Inter', system-ui, sans-serif;
  font-size:var(--fs-body-s);
  line-height:var(--lh-body-s);
  font-weight:400;
  color:var(--ink);
}

/* ---------- Tablet (>=768px): 8 columns, 32px margin, 20px gutter ---------- */

@media (min-width:768px){
  :root{
    --grid-margin:32px;
    --grid-columns:8;
    /* .process's nominal width: 4 of the 8 columns */
    --process-basis: calc(var(--col-width) * 4 + var(--grid-gutter) * 3);
  }

  .page{ padding:48px var(--grid-margin) 16px; }

  .hero{
    grid-template-columns:repeat(8, 1fr);
    column-gap:var(--grid-gutter);
    align-items:start;
  }

  .hero-left{ grid-column:1 / span 4; }
  .hero-right{ grid-column:5 / span 4; }

  .folio-grid{
    display:flex;
    flex-wrap:wrap;
    column-gap:var(--grid-gutter);
    row-gap:32px;
    align-items:flex-start;
  }

  /* .projects normally holds to its nominal column width (min-width),
     which keeps .process's left edge aligned with .hero-right/About
     above it. Once tile content needs MORE than that reserved width,
     .projects grows past it and .process no longer fits on the same
     row, so it drops to its own full-width row below — like mobile. */
  .projects{ flex:0 1 auto; min-width:var(--process-basis); }
  .process{ flex:0 1 var(--process-basis); min-width:0; }

  .footer-row,
  .site-footer-row{
    flex-direction:row;
    justify-content:space-between;
    align-items:center;
  }
}

/* ---------- Desktop (>=1200px): content uses 10 of the 12 columns, ---------- */
/* effective margin 125px at the 1280px reference frame; beyond 1280px  */
/* the content locks at that width and centers instead of stretching.  */

@media (min-width:1200px){
  :root{
    --grid-margin:125px;
    --grid-columns:10;
    /* Content locks at 1280px past this breakpoint instead of stretching,
       so column width is based on whichever is smaller. */
    --content-width: calc(min(100cqw, 1280px) - 2 * var(--grid-margin));
    /* .process's nominal width: 5 of the 10 columns */
    --process-basis: calc(var(--col-width) * 5 + var(--grid-gutter) * 4);
  }

  .page{
    max-width:1280px;
    margin-inline:auto;
    padding:64px var(--grid-margin) 16px;
  }

  .hero{ grid-template-columns:repeat(10, 1fr); }

  .hero-left{ grid-column:1 / span 5; }
  .hero-right{ grid-column:6 / span 5; }
}
