/* ==========================================================================
   Ekholmen Group
   Single stylesheet. No framework, no build step.
   Sections: 1 fonts, 2 tokens, 3 reset, 4 layout, 5 typography,
             6 header/footer, 7 components, 8 pages, 9 utilities
   ========================================================================== */

/* 1. Fonts ---------------------------------------------------------------- */

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url('../fonts/newsreader-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url('../fonts/newsreader-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: 'Newsreader';
  font-style: italic;
  font-weight: 300 400;
  font-display: swap;
  src: url('../fonts/newsreader-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 300 400;
  font-display: swap;
  src: url('../fonts/newsreader-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: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('../fonts/instrumentsans-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: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('../fonts/instrumentsans-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;
}

/* 2. Tokens --------------------------------------------------------------- */

:root {
  /* Colour. Drawn from the two photographs. See DESIGN_NOTES.md. */
  --paper:      #f4f2ed;  /* warm off-white, oak sapwood */
  --paper-sunk: #eae7de;  /* one step down, for hover and quiet panels */
  --ink:        #16191b;  /* near-black with a cold cast */
  --deep:       #1e3446;  /* deep water. Dark ground and link colour */
  --deep-soft:  #2b465b;  /* deep, one step up */
  --slate:      #55636d;  /* distant haze. Secondary text, AA on paper */
  --rule:       #d7d2c7;  /* hairlines, warm */
  --rule-dark:  #3a5266;  /* hairlines on the dark ground */
  --oak:        #7a6142;  /* used sparingly, small marks only */

  --font-serif: 'Newsreader', 'Iowan Old Style', 'Hoefler Text', Georgia, serif;
  --font-sans:  'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
                Helvetica, Arial, sans-serif;

  /* Type scale */
  --t-display: clamp(2.4rem, 1.15rem + 4.7vw, 4.75rem);
  --t-h2:      clamp(1.65rem, 1.2rem + 1.7vw, 2.5rem);
  --t-h3:      clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem);
  --t-lead:    clamp(1.09rem, 1.01rem + 0.4vw, 1.3rem);
  --t-body:    1.0625rem;
  --t-small:   0.95rem;
  --t-meta:    0.72rem;

  /* Rhythm */
  --gutter:    clamp(1.375rem, 5vw, 4.5rem);
  --maxw:      74rem;
  --section:   clamp(3.75rem, 9vw, 8rem);
  --measure:   34rem;
  --measure-w: 44rem;
}

/* 3. Reset ---------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.62;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, picture, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; }
button, input, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--deep);
  outline-offset: 3px;
  border-radius: 1px;
}
.on-dark :focus-visible { outline-color: var(--paper); }

/* 4. Layout --------------------------------------------------------------- */

/* Named-line grid. Children sit in the content column; .full spans edge to
   edge. Avoids 100vw and therefore avoids scrollbar overflow. */
.page {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [content-start] minmax(0, var(--maxw))
    [content-end] minmax(var(--gutter), 1fr)
    [full-end];
}
.page > * { grid-column: content; }
.page > .full { grid-column: full; }

/* Twelve columns inside the content column, at desktop widths only. */
.cols {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: clamp(1rem, 2.5vw, 2.25rem);
  row-gap: clamp(1.75rem, 4vw, 3rem);
}
@media (max-width: 899px) {
  .cols { display: block; }
  .cols > * + * { margin-top: 1.75rem; }
}

.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(2.5rem, 6vw, 4.5rem); }

/* 5. Typography ----------------------------------------------------------- */

.display {
  font-size: var(--t-display);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.021em;
  text-wrap: balance;
  max-width: 16ch;
}
.display--wide { max-width: 20ch; }

h2, .h2 {
  font-size: var(--t-h2);
  font-weight: 300;
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
h3, .h3 {
  font-size: var(--t-h3);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.008em;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.52;
  max-width: var(--measure);
}
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 1.1em; }
.prose-wide { max-width: var(--measure-w); }

.label {
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--slate);
  line-height: 1;
}
.on-dark .label { color: #9fb3c2; }

.meta {
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--slate);
}
.muted { color: var(--slate); }

/* A rule that sits under a label and above the block it introduces. */
.rule-top { border-top: 1px solid var(--rule); padding-top: 1.1rem; }
.on-dark .rule-top { border-top-color: var(--rule-dark); }

/* Links in running text */
.prose a, .lead a, .link {
  color: var(--deep);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, var(--deep) 35%, transparent);
  transition: text-decoration-color 140ms ease;
}
.prose a:hover, .lead a:hover, .link:hover { text-decoration-color: var(--deep); }

/* 6. Header and footer ---------------------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  background: var(--deep);
  color: var(--paper);
  padding: 0.75rem 1rem;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  text-decoration: none;
}
.skip:focus { left: 0; }

.site-head {
  border-bottom: 1px solid var(--rule);
}
/* Width matches the page grid: content column plus its two gutters. This keeps
   the wordmark on the same left edge as every heading on the site. */
.site-head__in {
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding: 1.375rem var(--gutter);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
}

/* Wordmark. Typographic stand-in, trivial to replace with an SVG logo. */
.wordmark {
  font-family: var(--font-serif);
  font-size: 1.28rem;
  font-weight: 400;
  letter-spacing: 0.005em;
  text-decoration: none;
  white-space: nowrap;
  color: var(--ink);
}
.wordmark span { color: var(--slate); font-weight: 300; }
.on-dark .wordmark { color: var(--paper); }
.on-dark .wordmark span { color: #9fb3c2; }

/* Nav and language switch share the right-hand side of the header. */
.head-right {
  display: flex;
  align-items: baseline;
  gap: clamp(1.25rem, 3vw, 2.5rem);
}

.nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.1rem, 2.6vw, 2.1rem);
}

/* Language switch. Two links and a hairline divider, nothing more. */
.lang {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  white-space: nowrap;
}
.lang a {
  color: var(--slate);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: color 140ms ease, border-color 140ms ease;
}
.lang a:hover { color: var(--ink); border-bottom-color: var(--rule); }
.lang a[aria-current='true'] { color: var(--ink); border-bottom-color: var(--ink); }
.lang span { color: var(--rule); }
.site-foot .lang a { color: var(--paper); opacity: 0.78; }
.site-foot .lang a:hover,
.site-foot .lang a[aria-current='true'] { opacity: 1; border-bottom-color: transparent; }
.site-foot .lang span { color: var(--rule-dark); }
.nav a {
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--slate);
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: color 140ms ease, border-color 140ms ease;
}
.nav a:hover { color: var(--ink); border-bottom-color: var(--rule); }
.nav a[aria-current='page'] { color: var(--ink); border-bottom-color: var(--ink); }

@media (max-width: 599px) {
  .site-head__in {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.9rem;
    padding-block: 1.1rem 0.9rem;
  }
  /* Five nav items wrap to two rows on a phone. Anchoring the language switch
     to the last row keeps it attached to the block rather than floating. */
  .head-right {
    width: 100%;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
  }
  .nav ul { row-gap: 0.55rem; }
  .nav ul { gap: 1.05rem; }
  .nav a, .lang { font-size: 0.685rem; letter-spacing: 0.085em; }
}

.site-foot {
  background: var(--deep);
  color: var(--paper);
  margin-top: auto;
}
.site-foot__in {
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding: clamp(2rem, 4vw, 2.75rem) var(--gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.25rem 2rem;
}
.site-foot a { color: var(--paper); }
.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  font-family: var(--font-sans);
  font-size: 0.8125rem;
}
.foot-links a { text-decoration: none; opacity: 0.78; transition: opacity 140ms ease; }
.foot-links a:hover { opacity: 1; text-decoration: underline; text-underline-offset: 0.2em; }
.foot-legal {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  color: #9fb3c2;
}

/* 7. Components ----------------------------------------------------------- */

/* 7a. Index rows. The landing page contents list. Not cards, on purpose. */
.index { padding-block: clamp(2.75rem, 6vw, 4.75rem); }
.idx:first-child { border-top: 1px solid var(--rule); }

.idx {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 15rem) minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: clamp(1rem, 2.5vw, 2.25rem);
  padding-block: clamp(1.6rem, 3.4vw, 2.4rem);
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  transition: background-color 150ms ease;
}
.idx:hover { background-color: var(--paper-sunk); }
.idx__n {
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--oak);
  font-variant-numeric: tabular-nums;
}
.idx__t {
  font-size: var(--t-h3);
  font-weight: 400;
  letter-spacing: -0.008em;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  text-decoration-color: transparent;
  transition: text-decoration-color 150ms ease;
}
.idx:hover .idx__t { text-decoration-color: var(--ink); }
.idx__d { color: var(--slate); font-size: var(--t-small); max-width: 34ch; }
.idx__cta {
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--deep);
  white-space: nowrap;
}
.idx__cta i {
  font-style: normal;
  display: inline-block;
  transition: transform 150ms ease;
}
.idx:hover .idx__cta i { transform: translateX(4px); }

@media (max-width: 899px) {
  .idx {
    grid-template-columns: 2.5rem 1fr;
    row-gap: 0.4rem;
  }
  .idx__n { grid-row: 1; }
  .idx__t { grid-column: 2; }
  .idx__d { grid-column: 2; }
  .idx__cta { grid-column: 2; margin-top: 0.35rem; }
}

/* 7b. Standalone call to action, used at the foot of pages. */
.cta {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--deep);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.4rem;
  transition: border-color 150ms ease;
}
.cta i { font-style: normal; display: inline-block; transition: transform 150ms ease; }
.cta:hover { border-bottom-color: var(--deep); }
.cta:hover i { transform: translateX(4px); }
.on-dark .cta { color: var(--paper); border-bottom-color: var(--rule-dark); }
.on-dark .cta:hover { border-bottom-color: var(--paper); }

/* 7c. Images */
.band img {
  width: 100%;
  object-fit: cover;
  aspect-ratio: 3 / 2;
}
@media (min-width: 720px) {
  .band img { aspect-ratio: 2.4 / 1; }
}
.band--oak img { aspect-ratio: 3 / 2; }
@media (min-width: 720px) {
  .band--oak img { aspect-ratio: 3.2 / 1; }
}


/* 7d. Dark band */
.dark {
  background: var(--deep);
  color: var(--paper);
}
.dark .display, .dark h2, .dark h3 { color: var(--paper); }
.dark__in {
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--section) var(--gutter);
}

/* 7e. Statement list. Short lines separated by hairlines. */
.statements { border-top: 1px solid var(--rule-dark); }
.statements li {
  border-bottom: 1px solid var(--rule-dark);
  padding-block: clamp(0.85rem, 2vw, 1.15rem);
  font-size: clamp(1.15rem, 0.95rem + 0.85vw, 1.7rem);
  font-weight: 300;
  line-height: 1.28;
  letter-spacing: -0.01em;
  max-width: 46ch;
  text-wrap: balance;
}

/* 7f. Definition list, used for what happens after we buy. The four terms are
   the four parts of one promise, so one unbroken hairline runs down the left
   rather than rules cutting between them, with a short tick joining each term
   to that line and its explanation hanging underneath in the quieter voice. */
.terms {
  display: grid;
  row-gap: clamp(1.45rem, 3.2vw, 2.4rem);
  padding-left: var(--terms-indent);
  border-left: 1px solid var(--rule);
  --terms-indent: clamp(1.15rem, 3vw, 2.35rem);
}
.terms > div { position: relative; }
.terms > div::before {
  content: "";
  position: absolute;
  top: 0.62em;
  left: calc(var(--terms-indent) * -1);
  width: clamp(0.5rem, 1.3vw, 0.95rem);
  border-top: 1px solid var(--rule);
}
.terms dt {
  font-size: clamp(1.3rem, 1.02rem + 1.1vw, 1.95rem);
  font-weight: 300;
  line-height: 1.19;
  letter-spacing: -0.014em;
  text-wrap: balance;
  max-width: 26ch;
}
.terms dd {
  color: var(--slate);
  font-size: var(--t-small);
  max-width: 46ch;
  margin-top: 0.5rem;
}

/* 7g. Team. Portraits in a row, four across, squared off rather than circular.
   The photograph carries the identity, so the name sits under it as a caption
   rather than beside it. */
.people {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: clamp(0.9rem, 2.1vw, 1.85rem);
  row-gap: clamp(1.75rem, 3.5vw, 2.5rem);
  border-top: 1px solid var(--rule);
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
}
/* Subgrid keeps the photo, name and role lines aligned across the row even
   when one name wraps and the others do not. Degrades harmlessly without it. */
.people li {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4;   /* photo, name, role, LinkedIn */
  row-gap: 0;
  align-content: start;
}
.people img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  background: var(--paper-sunk);
  margin-bottom: 0.95rem;
}
.people .name {
  display: block;
  font-size: var(--t-h3);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.008em;
}
.people .role {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--slate);
}
@media (max-width: 899px) {
  .people { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 7h. Empty state. Deliberately quiet, deliberately roomy. */
.empty {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding-block: clamp(3.25rem, 9vw, 6.5rem);
}
.empty p {
  font-size: clamp(1.2rem, 1rem + 0.9vw, 1.75rem);
  font-weight: 300;
  line-height: 1.35;
  letter-spacing: -0.012em;
  max-width: 26ch;
  color: var(--ink);
}
/* Needs to restate size and colour: `.empty p` above is more specific than
   the `.meta` class on its own and would otherwise win both. */
.empty .meta {
  margin-top: 1.5rem;
  max-width: 46ch;
  font-size: 0.95rem;
  line-height: 1.6;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--slate);
}

/* 7i. Company list. Empty at launch. Markup template in companies.html. */
.companies { border-top: 1px solid var(--rule); }
.companies li {
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr) auto;
  column-gap: clamp(1rem, 2.5vw, 2.25rem);
  align-items: baseline;
  padding-block: clamp(1.15rem, 2.6vw, 1.7rem);
  border-bottom: 1px solid var(--rule);
}
.companies .co-name { font-size: var(--t-h3); font-weight: 400; letter-spacing: -0.008em; }
.companies .co-desc { color: var(--slate); font-size: var(--t-small); max-width: 46ch; }
.companies .co-link {
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--deep);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
}
.companies .co-link:hover { border-bottom-color: var(--deep); }
@media (max-width: 767px) {
  .companies li { grid-template-columns: 1fr; row-gap: 0.35rem; }
}

/* 7j. News list. Empty at launch. Markup template in news.html. */
.news { border-top: 1px solid var(--rule); }
.news li {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  column-gap: clamp(1rem, 2.5vw, 2.25rem);
  padding-block: clamp(1.35rem, 3vw, 2.1rem);
  border-bottom: 1px solid var(--rule);
}
.news time {
  font-family: var(--font-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--slate);
  line-height: 1.9;
}
.news h3 { margin-bottom: 0.3rem; }
.news p { color: var(--slate); font-size: var(--t-small); max-width: 52ch; }
@media (max-width: 599px) {
  .news li { grid-template-columns: 1fr; row-gap: 0.45rem; }
  .news time { line-height: 1; }
}

/* 7k. Big email link */
/* An email address is a long lowercase string with an @ in it. At display size
   and weight 300 it reads thin and sits outside the type scale, so it is set
   closer to the heading sizes and at text weight. */
.mail {
  display: inline-block;
  font-size: clamp(1.3rem, 1.05rem + 1.05vw, 1.9rem);
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.14em;
  text-decoration-color: var(--rule);
  overflow-wrap: anywhere;
  transition: text-decoration-color 150ms ease;
}
.mail:hover { text-decoration-color: var(--ink); }
/* Smaller variant for the landing page, where the email is a closing note
   rather than the point of the page. */
.mail--sm { font-size: clamp(1.1rem, 1rem + 0.6vw, 1.4rem); }

/* 8. Page-specific --------------------------------------------------------- */

.site { display: flex; flex-direction: column; min-height: 100vh; }
.site > main { flex: 1 0 auto; }

/* Hero. Photograph with the opening statement set over it, bottom left, on the
   same left edge as the rest of the site. The scrim is a soft bottom-up
   gradient in the brand blue, not a flat dark box: the lower part of the
   photograph is already deep water, so it needs very little help. */
.hero {
  position: relative;
  display: grid;
  min-height: clamp(30rem, 80vh, 46rem);
  isolation: isolate;
}
.hero > * { grid-area: 1 / 1; }

/* Out of flow for the same reason as the announcement band: left in flow, the
   image's own aspect ratio can end up dictating the height of the hero rather
   than min-height doing it. */
.hero__media,
.hero__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* Positioned elements paint above non-positioned siblings, so the three
   layers are ordered explicitly. Without this the photograph covers the
   scrim and the headline. */
.hero__media { z-index: 0; }
.hero__media img {
  object-fit: cover;
  object-position: 50% 58%;
}

/* Two gradients rather than one flat overlay. The first follows the text down
   the left edge, the second lifts the base. Where there is no text the
   photograph is left alone. */
.hero__scrim {
  z-index: 1;
  background:
    linear-gradient(
      to right,
      rgba(13, 25, 35, 0.68) 0%,
      rgba(13, 25, 35, 0.58) 30%,
      rgba(13, 25, 35, 0.34) 58%,
      rgba(13, 25, 35, 0) 80%
    ),
    linear-gradient(
      to top,
      rgba(13, 25, 35, 0.36) 0%,
      rgba(13, 25, 35, 0.32) 50%,
      rgba(13, 25, 35, 0.26) 80%,
      rgba(13, 25, 35, 0.16) 100%
    );
}

/* Centred vertically, still left aligned. Bottom-anchoring worked when the
   opening was three short lines; with a fuller paragraph the block grew
   upward and left a dead band of sky above it while hugging the bottom edge. */
.hero__inner {
  z-index: 2;
  align-self: center;
  width: 100%;
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding: clamp(1.5rem, 4vw, 2.5rem) var(--gutter);
  color: var(--paper);
  text-shadow: 0 1px 30px rgba(8, 18, 26, 0.4);
}
.hero__inner .label {
  color: #cddae4;
  margin-bottom: clamp(1.1rem, 2.6vw, 1.75rem);
}
.hero__inner .display { color: var(--paper); }
.hero__side {
  margin-top: clamp(1.35rem, 3vw, 2rem);
  font-size: 1rem;
  line-height: 1.55;
  max-width: 40ch;
  color: #e4e6e4;
}

/* Below the fold on a phone the block is proportionally larger, so give the
   text a little more ground to sit on. */
@media (max-width: 719px) {
  .hero { min-height: clamp(32rem, 86vh, 44rem); }
  .hero__scrim {
    background: linear-gradient(
      to top,
      rgba(13, 25, 35, 0.84) 0%,
      rgba(13, 25, 35, 0.70) 34%,
      rgba(13, 25, 35, 0.38) 62%,
      rgba(13, 25, 35, 0.08) 85%,
      rgba(13, 25, 35, 0) 100%
    );
  }
  .hero__inner { padding-bottom: clamp(2.25rem, 7vw, 3.25rem); }
}

/* Full-width block: label on top, content across the whole content column.
   Used where a section needs more room than the indented two-column pattern. */
.block { padding-block: clamp(2.5rem, 6vw, 4.25rem); }
.block > .label { display: block; margin-bottom: clamp(1.5rem, 3.2vw, 2.25rem); }

/* Closing contact block on the landing page. Sits on the same left edge as the
   index rows above it, rather than indenting into a second column. */
.closing { padding-block: clamp(2.25rem, 5vw, 3.5rem) clamp(3rem, 7vw, 5.5rem); }
.closing .label { display: block; margin-bottom: clamp(1.5rem, 3.2vw, 2.25rem); }
.closing__body > * + * { margin-top: 1.5rem; }
.closing__lead {
  font-size: var(--t-body);
  line-height: 1.62;
  max-width: 54ch;
}

/* Page heads on inner pages */
.pagehead { padding-block: clamp(2.75rem, 6.5vw, 5rem) clamp(2rem, 4.5vw, 3.25rem); }
.pagehead .label { display: block; margin-bottom: clamp(1.25rem, 3vw, 2rem); }
.pagehead .display { margin-bottom: 1.5rem; }
.pagehead .lead { color: var(--slate); }

/* Two-up: heading in a narrow left column, content on the right. */
.twoup .twoup__head { grid-column: 1 / span 3; }
.twoup .twoup__body { grid-column: 5 / span 8; }
@media (max-width: 1099px) and (min-width: 900px) {
  .twoup .twoup__head { grid-column: 1 / span 4; }
  .twoup .twoup__body { grid-column: 5 / span 8; }
}

/* 9. Utilities ------------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.stack-sm > * + * { margin-top: 0.85rem; }
.stack-md > * + * { margin-top: 1.5rem; }
.stack-lg > * + * { margin-top: clamp(2rem, 4vw, 3rem); }

@media print {
  .site-head, .site-foot, .band { display: none; }
  body { background: #fff; color: #000; }
}

/* Footer and team icons. Both marks are inlined in the markup and filled with
   currentColor, so one copy serves both grounds: paper on the dark footer,
   deep blue in the team row. Monochrome rather than brand colours, which keeps
   this palette intact and stops two logos fighting each other.
   The padding is for the tap target, not for looks: the discs are around 20px,
   which is under the comfortable minimum on a phone. */
.icon-mark {
  width: 100%;
  height: 100%;
  fill: currentColor;
  display: block;
}

/* Icon link on the paper ground: LinkedIn under a team member, and the
   website mark under the owner note. Same size in both places so the page
   has one icon language rather than two. */
.mark-link {
  display: block;
  justify-self: start;
  align-self: start;
  width: 1.4rem;
  height: 1.4rem;
  box-sizing: content-box;
  padding: 4px;
  margin: 0.7rem 0 0 -4px;
  color: var(--deep);
  opacity: 0.85;
  transition: opacity 140ms ease;
}
.mark-link:hover { opacity: 1; }
.twoup__body > .mark-link { margin-top: 1.15rem; }

/* Brand group: wordmark with the two marks beside it, on the left of the
   footer. Centred against the wordmark rather than baseline aligned, because
   a disc has no baseline to sit on. */
.foot-brand {
  display: flex;
  align-items: center;
  gap: clamp(0.85rem, 1.8vw, 1.3rem);
}
.foot-social {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: -4px;
}
.foot-social .icon-link {
  display: block;
  width: 1.15rem;
  height: 1.15rem;
  box-sizing: content-box;
  padding: 4px;
  opacity: 0.78;
  transition: opacity 140ms ease;
}
.foot-social .icon-link:hover { opacity: 1; }

/* 7l. Announcement band. A heavily blurred photograph with centred text, used
   where a page has nothing to list yet. The source is deliberately tiny, 80px
   wide, and scaled up: that is both the cheapest possible blur and the
   smoothest, and the whole file is under 3 KB. The CSS blur on top removes any
   residual structure, and the slight scale hides the soft edge blur creates.

   This is the one centred block on the site. Everything else is left aligned,
   which is deliberate, so keep this the exception rather than the pattern. */
.notice {
  position: relative;
  display: grid;
  align-self: start;
  min-height: clamp(13rem, 24vw, 19rem);
  overflow: hidden;
  isolation: isolate;
}
.notice > * { grid-area: 1 / 1; }

/* The two background layers are taken out of flow on purpose. Left in flow,
   the image's height:100% resolves against an auto-height parent, falls back
   to auto, and the image's own 2:1 ratio then dictates the height of the whole
   band. Absolute positioning lets min-height and the text decide instead, and
   object-fit does the cropping.

   The blur and the scale each also make the image its own stacking context, so
   the layers are ordered explicitly or the image paints over the text. */
.notice__bg,
.notice__scrim {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.notice__bg {
  object-fit: cover;
  filter: blur(26px) saturate(0.85);
  transform: scale(1.14);
  z-index: 0;
}
.notice__scrim { background: rgba(13, 25, 35, 0.62); z-index: 1; }

.notice__inner {
  place-self: center;
  z-index: 2;
  text-align: center;
  max-width: 32rem;
  padding: clamp(2.25rem, 5vw, 3.25rem) var(--gutter);
  color: var(--paper);
}
.notice__title {
  font-size: clamp(1.9rem, 1.3rem + 2.3vw, 3rem);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.018em;
  text-wrap: balance;
}
.notice__sub a {
  color: var(--paper);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: rgba(244, 242, 237, 0.45);
  transition: text-decoration-color 140ms ease;
}
.notice__sub a:hover { text-decoration-color: var(--paper); }

.notice__sub {
  margin-top: 0.85rem;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: #dbe1e6;
  text-wrap: balance;
}
