/* SMDS Solutions — smds.be
   Built on the corporate identity v1.0 (13 October 2026): see corporate-id/
   in this repo for the colours, the type and the logo files. Every colour
   here comes from corporate-id/colours/smds-colours.css. */

/* Unbounded (display) and Manrope (text), self-hosted: a page that pulls a
   font from Google asks the visitor's browser to talk to a third party, and
   this site's privacy policy promises it does not. Latin subset only. */
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/assets/fonts/unbounded-600.woff2') format('woff2'); }
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/assets/fonts/unbounded-700.woff2') format('woff2'); }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/assets/fonts/manrope-500.woff2') format('woff2'); }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/assets/fonts/manrope-600.woff2') format('woff2'); }

:root {
  --navy: #0b1526;
  --teal: #10b3a3;
  --teal-ink: #0b7a70;
  --slate: #5a6577;
  --mist: #9aa6b8;
  --line: #e2e6eb;
  --cloud: #f3f5f7;
  --white: #ffffff;
  /* The portfolio cards: a tinted panel on the cloud page -- light, but not
     the paper white the page started out as (Dave picked D of five, second
     thought, 13 October 2026). */
  --card: #eef2f7;
  --card-line: #dde3ec;

  --f-display: 'Unbounded', 'Arial Black', system-ui, sans-serif;
  --f-body: 'Manrope', 'Segoe UI', system-ui, sans-serif;

  --max-width: 1120px;
  --text-width: 760px;
  /* The hero's title, and with it the mark beside it. Bigger than the page's
     other headings: with the mark it fills the column the facts card sits in. */
  --hero-title: clamp(2.2rem, 6vw, 5.5rem);
  /* One distance between a page's content and the button that leads away
     from it, on every page, scaling with the screen. */
  --button-gap: clamp(44px, 6vw, 68px);
  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 1px 2px rgba(11, 21, 38, 0.04), 0 8px 24px rgba(11, 21, 38, 0.06);
  --shadow-lift: 0 2px 4px rgba(11, 21, 38, 0.05), 0 16px 40px rgba(11, 21, 38, 0.1);
}

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

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  background: var(--white);
  color: var(--navy);
  font-family: var(--f-body);
  font-weight: 500;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* The brand's two colours as a hairline across the top of every page. */
.top-decoration {
  height: 3px;
  background: linear-gradient(90deg, var(--navy) 0%, var(--teal) 70%);
}

/* ---------------------------------------------------------------- header */

header {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 16px max(20px, calc((100% - var(--max-width)) / 2));
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.brand a { display: block; line-height: 0; }
.brand img { height: 30px; width: auto; }

.header-right { display: flex; align-items: center; gap: 16px; }

.lang-switcher { display: flex; gap: 2px; }

.lang-switcher a {
  padding: 6px 9px;
  border-radius: 8px;
  color: var(--slate);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

.lang-switcher a:hover { color: var(--navy); background: var(--cloud); }
.lang-switcher a.active { color: var(--teal-ink); background: rgba(16, 179, 163, 0.12); }

.menu-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0 11px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
}

.menu-toggle span { display: block; height: 2px; border-radius: 2px; background: var(--navy); }
.menu-toggle:hover { border-color: var(--navy); }

.menu-panel {
  position: absolute;
  right: max(20px, calc((100% - var(--max-width)) / 2));
  z-index: 50;
  display: flex;
  flex-direction: column;
  min-width: 236px;
  margin-top: 8px;
  padding: 10px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
}

/* display:flex on .menu-panel would otherwise beat the browser's own rule for
   the hidden attribute, and the menu would stand open on every page. */
.menu-panel[hidden] { display: none; }

.menu-panel a {
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
}

.menu-panel a:hover { background: var(--cloud); }
.menu-panel a.active { color: var(--teal-ink); background: rgba(16, 179, 163, 0.1); }
.menu-panel a.submenu { padding-left: 30px; color: var(--slate); font-weight: 500; font-size: 0.95rem; }

/* ------------------------------------------------------------ breadcrumb */

.breadcrumb { border-bottom: 1px solid var(--line); background: var(--white); }

.breadcrumb-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 12px 20px;
  color: var(--slate);
  font-size: 0.85rem;
}

.breadcrumb-inner a { color: var(--slate); text-decoration: none; }
.breadcrumb-inner a:hover { color: var(--teal-ink); }
.breadcrumb-inner .sep { margin: 0 8px; color: var(--mist); }
.breadcrumb-inner .current { color: var(--navy); font-weight: 600; }

/* ------------------------------------------------------------------ hero */

.hero {
  padding: clamp(56px, 9vw, 112px) 20px clamp(96px, 11vw, 150px);
  background:
    radial-gradient(90% 120% at 88% 6%, rgba(16, 179, 163, 0.28) 0%, rgba(16, 179, 163, 0) 58%),
    var(--navy);
  color: var(--white);
}

/* One column for everything in the hero. It used to be `.hero > *`, which the
   paragraph's own max-width and margin overrode -- so on a wide screen the
   title and the buttons sat in the centred column while the two lines of text
   hugged the left edge of the window (Dave, 13 October 2026). */
.hero-inner { max-width: var(--max-width); margin-inline: auto; }


/* The mark stands as tall as the two lines beside it -- eyebrow and title --
   rather than sitting at a fixed 56 px, and the text starts further from it
   (Dave, 13 October 2026). */
/* The mark and the title keep the proportions of the brand's own horizontal
   logo (Dave, 13 October 2026). Measured off corporate-id's
   smds-logo-horizontal-colour.svg: the mark is 1.33 times the height of the
   wordmark's capitals, and the space between them 0.86 of it. Unbounded's
   capitals measure 0.77 of the type size, which is where these two multiples
   come from. */
.hero .lockup {
  display: flex;
  align-items: center;
  gap: calc(var(--hero-title) * 0.66);
  margin-bottom: 26px;
}

.hero .icon {
  width: auto;
  height: calc(var(--hero-title) * 1.02);
  /* Centred on the capitals of the title, not on the title plus the eyebrow
     above it (Dave, 13 October 2026). Two terms: half of what the eyebrow
     occupies -- its line box plus the gap under it -- and 0.163 of the type
     size, which is how far the mark's own artwork sits above the middle of
     the capitals it stands beside. Measured, not guessed. */
  margin-top: calc((var(--tag-size) * 1.65 + 10px) / 2 + var(--hero-title) * 0.163);
}
/* The mark in motion. Arrival: brackets open outwards, the wave draws itself
   from left to right. Then, in step with the wave's roll (see generate.py),
   the brackets give way by a few units and come back. Lengths are in the
   artwork's own units, so it scales with the title. */
.hero-mark { overflow: visible; }
@keyframes mark-in-left { from { transform: translateX(26px); opacity: 0; } }
@keyframes mark-in-right { from { transform: translateX(-26px); opacity: 0; } }
@keyframes mark-draw { from { stroke-dashoffset: 1; opacity: 0; } 15% { opacity: 1; } to { stroke-dashoffset: 0; opacity: 1; } }
@keyframes mark-give-left { 0%, 50%, 100% { transform: translateX(0); } 68% { transform: translateX(-5px); } }
@keyframes mark-give-right { 0%, 50%, 100% { transform: translateX(0); } 68% { transform: translateX(5px); } }
.hero-mark .mark-left {
  animation: mark-in-left .8s cubic-bezier(.2, .8, .2, 1) both,
             mark-give-left 5s ease-in-out 1.3s infinite;
}
.hero-mark .mark-right {
  animation: mark-in-right .8s cubic-bezier(.2, .8, .2, 1) both,
             mark-give-right 5s ease-in-out 1.3s infinite;
}
.hero-mark .mark-wave {
  stroke-dasharray: 1;
  animation: mark-draw .9s cubic-bezier(.6, 0, .2, 1) .3s both;
}
@media (prefers-reduced-motion: reduce) {
  .hero-mark .mark-left, .hero-mark .mark-right, .hero-mark .mark-wave { animation: none; }
}

.hero .lockup-text { display: flex; flex-direction: column-reverse; gap: 10px; }

.hero h1 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--hero-title);
  letter-spacing: -0.02em;
  line-height: 1.05;
  text-wrap: balance;
}

/* The tagline runs exactly as wide as the "SM" under it (Dave, 13 October
   2026). Measured: the ink of "SM" in Unbounded is 1.953 of the title's type
   size, the tagline's own letters 9.04 of its own, and there are sixteen
   gaps between them to take up the difference -- so the spacing is computed,
   not chosen. The left padding puts the F over the edge of the S, whose
   side bearing is wider. Below about 810 px the title gets too small for
   legible type to fit inside "SM"; there the tagline stays at its smallest
   readable size and runs a little past the M. */
.hero { --tag-size: clamp(0.625rem, calc(var(--hero-title) * 0.172), 0.78rem); }

.hero .tagline {
  margin: 0;
  padding-left: calc(var(--hero-title) * 0.036 - 0.07em);
  color: var(--teal);
  font-weight: 600;
  font-size: var(--tag-size);
  letter-spacing: max(0.03em, calc((var(--hero-title) * 1.953 - 9.04em) / 16));
  white-space: nowrap;
  text-transform: uppercase;
}

.hero p.body-text {
  max-width: 56ch;
  margin: 0 0 14px;
  color: var(--mist);
  font-size: clamp(1.02rem, 1.6vw, 1.16rem);
}

.hero p.body-text:last-child { margin-bottom: 0; }
.hero p.body-text a { color: var(--white); text-decoration-color: rgba(255,255,255,0.4); text-underline-offset: 3px; }
.hero p.body-text a:hover { color: var(--teal); }

/* The two calls to action under the hero text: the first is the loud one. */
/* A grid, not a flex row: the two buttons each take their own width, and the
   third spans both columns, so it ends exactly where the pair ends rather
   than at the edge of the page (Dave, 13 October 2026). A wrapping flex row
   cannot do this -- its max-content width is all three on one line. */
/* One line, three buttons (Dave, 13 October 2026): the teal one takes the
   width of its words, and the white and the dark one share what is left in
   equal halves, so the row ends where the title above it does. */
.cta-list {
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  gap: 14px;
  margin-top: 34px;
}


.cta-item {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 13px 22px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  font-weight: 600;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

/* The whole pill is the link -- a button that only answers to the two words
   inside it is a button that misses (Dave, 13 October 2026). */
.cta-item { color: var(--white); text-decoration: none; }
.cta-item:first-child { background: var(--teal); border-color: var(--teal); color: var(--navy); }
.cta-item:hover { transform: translateY(-1px); }
.cta-item:first-child:hover { background: #0fc4b2; }
.cta-item:not(:first-child):hover { background: rgba(255, 255, 255, 0.08); border-color: rgba(255,255,255,0.45); }
.cta-item:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; }
.cta-bubble { font-size: 0.95rem; line-height: 1; }

/* Two arrows on the fast one (Dave, 13 October 2026), with air between them. */
.cta-bubble-double { letter-spacing: 0.1em; }

/* The white one, in the middle: three buttons, three weights -- teal, white,
   outline. */
.cta-list .cta-item.cta-wide {
  background: var(--white);
  border-color: var(--white);
  color: var(--navy);
}

.cta-list .cta-item.cta-wide:hover { background: var(--cloud); border-color: var(--cloud); }

/* Read from the other end: the label sits on the right and the arrow beyond
   it, turned around (Dave, 13 October 2026). */
.cta-list .cta-item.cta-wide {
  flex-direction: row-reverse;
  justify-content: flex-start;
  text-align: right;
}

.cta-list .cta-item.cta-wide .cta-bubble { transform: scaleX(-1); }

/* --------------------------------------------------- how (fast) it works */

.how-intro { margin: 0 0 34px; font-size: 1.12rem; color: var(--slate); }

/* The steps: a time marker in the margin, the step beside it, and a line down
   the left that ties them into one run. */
.steps {
  margin: 0;
  padding: 0;
  list-style: none;
  border-left: 2px solid var(--line);
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 4px 22px;
  padding: 0 0 34px 26px;
}

.step::before {
  content: "";
  position: absolute;
  left: -7px;
  top: 7px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 4px var(--white);
}

/* A light runs down the timeline and starts again (Dave, 13 October 2026).
   One ten-second loop:
   - each dot swells and glows in turn, 0.75 s after the one above;
   - the wave in the margin lights up stretch by stretch just behind it and
     stays lit, so the line fills from the top down to the arrowhead;
   - the last dot, the release, keeps flashing for some five seconds;
   - then the line fades back and it starts over.
   Switched off for readers who ask for reduced motion. */
@keyframes step-dot {
  0%, 15%, 100% { transform: scale(1); background: var(--teal); box-shadow: 0 0 0 4px var(--white), 0 0 0 4px rgba(16, 179, 163, 0); }
  6% { transform: scale(1.55); background: #2fdccb; box-shadow: 0 0 0 3px var(--white), 0 0 14px 7px rgba(16, 179, 163, 0.55); }
}
@keyframes step-dot-last {
  0%, 30%, 41%, 53%, 65%, 77%, 89%, 100% { transform: scale(1); background: var(--teal); box-shadow: 0 0 0 4px var(--white), 0 0 0 4px rgba(16, 179, 163, 0); }
  35%, 47%, 59%, 71%, 83% { transform: scale(1.55); background: #2fdccb; box-shadow: 0 0 0 3px var(--white), 0 0 14px 7px rgba(16, 179, 163, 0.55); }
}
@keyframes step-flow-1 {
  0%, 1.3%, 96%, 100% { stroke: #8fd9d1; stroke-width: 7px; }
  6.3% { stroke: var(--teal); stroke-width: 10px; }
  11.3%, 88% { stroke: var(--teal); stroke-width: 7px; }
}
@keyframes step-flow-2 {
  0%, 8.8%, 96%, 100% { stroke: #8fd9d1; stroke-width: 7px; }
  13.8% { stroke: var(--teal); stroke-width: 10px; }
  18.8%, 88% { stroke: var(--teal); stroke-width: 7px; }
}
@keyframes step-flow-3 {
  0%, 16.3%, 96%, 100% { stroke: #8fd9d1; stroke-width: 7px; }
  21.3% { stroke: var(--teal); stroke-width: 10px; }
  26.3%, 88% { stroke: var(--teal); stroke-width: 7px; }
}
@keyframes step-flow-4 {
  0%, 23.8%, 96%, 100% { stroke: #8fd9d1; stroke-width: 7px; }
  28.8% { stroke: var(--teal); stroke-width: 10px; }
  33.8%, 88% { stroke: var(--teal); stroke-width: 7px; }
}
@keyframes step-flow-5 {
  0%, 30.5%, 96%, 100% { stroke: #8fd9d1; stroke-width: 7px; }
  35.5% { stroke: var(--teal); stroke-width: 10px; }
  40.5%, 88% { stroke: var(--teal); stroke-width: 7px; }
}
/* The step's title takes the same glow at the same moment as its dot. */
@keyframes step-title {
  0%, 15%, 100% { text-shadow: 0 0 0 rgba(16, 179, 163, 0); }
  6% { text-shadow: 0 0 16px rgba(16, 179, 163, 0.75), 0 0 4px rgba(16, 179, 163, 0.45); }
}
@keyframes step-title-last {
  0%, 30%, 41%, 53%, 65%, 77%, 89%, 100% { text-shadow: 0 0 0 rgba(16, 179, 163, 0); }
  35%, 47%, 59%, 71%, 83% { text-shadow: 0 0 16px rgba(16, 179, 163, 0.75), 0 0 4px rgba(16, 179, 163, 0.45); }
}
.step-body h2 { animation: step-title 10s ease-in-out infinite; }
.step:nth-child(2) .step-body h2 { animation-delay: 0.75s; }
.step:nth-child(3) .step-body h2 { animation-delay: 1.5s; }
.step:nth-child(4) .step-body h2 { animation-delay: 2.25s; }
.step:last-child .step-body h2 { animation-name: step-title-last; animation-delay: 0s; }
.step::before { animation: step-dot 10s ease-in-out infinite; }
.step:nth-child(2)::before { animation-delay: 0.75s; }
.step:nth-child(3)::before { animation-delay: 1.5s; }
.step:nth-child(4)::before { animation-delay: 2.25s; }
.step:last-child::before { animation-name: step-dot-last; animation-delay: 0s; }
/* A paler teal at rest, opaque: a see-through stroke would show darker where
   two stretches overlap at the joins. */
.step-flow path { stroke: #8fd9d1; animation: step-flow-1 10s ease-in-out infinite; }
.step:nth-child(1) .step-flow path { animation-name: step-flow-1; }
.step:nth-child(2) .step-flow path { animation-name: step-flow-2; }
.step:nth-child(3) .step-flow path { animation-name: step-flow-3; }
.step:nth-child(4) .step-flow path { animation-name: step-flow-4; }
.step:nth-child(5) .step-flow path { animation-name: step-flow-5; }

@media (prefers-reduced-motion: reduce) {
  .step::before { animation: none; }
  .step-body h2 { animation: none; }
  .step-flow path { animation: none; stroke: var(--teal); }
}

.step-time { margin: 0; display: flex; flex-direction: column; }

/* The doodle for each step stands in the margin left of the timeline, level
   with the number (Dave, 13 October 2026). Where the page has no margin to
   spare it moves inside, to the right of the number, and shrinks. */
.step-art { position: absolute; top: -10px; right: 0; width: 56px; height: 56px; }
.step-art svg { display: block; width: 100%; height: 100%; overflow: visible; }

@media (min-width: 960px) {
  .step-art { right: calc(100% + 34px); top: -18px; width: 88px; height: 88px; }
}

/* The wave down the far margin: only where there is room for it beyond the
   doodles. Each stretch starts level with its doodle's middle and runs to the
   next one's. */
.step-flow { display: none; }

@media (min-width: 1180px) {
  .step-flow {
    display: block;
    position: absolute;
    top: 26px;
    right: calc(100% + 34px + 88px + 22px);
    width: 60px;
    height: 100%;
  }
  .step-flow svg { display: block; width: 100%; height: 100%; overflow: visible; }
  .step-flow-end { height: 44px; }
}

.step-number {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--navy);
}

.step-unit {
  margin-top: 4px;
  color: var(--teal-ink);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.step-body h2 {
  margin: 0 0 6px;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}

.step-body p { margin: 0; color: var(--slate); }

.how-outro { margin: 10px 0 22px; font-weight: 600; font-size: 1.08rem; }

/* The three ways on from here: the loud one first, then back to the work and
   back to the start -- all three the same size, which they were not: the teal
   one had the body's type and the outlines a smaller one, and only the
   outlines carried a border (Dave, 13 October 2026). */
/* Two rows: the one loud button on its own, then the two ways out under it
   -- home under "Get in touch", the portfolio beside it (Dave, 13 October
   2026). The first column is as wide as its widest button, so the two that
   share it line up. */
.how-actions {
  display: grid;
  grid-template-columns: max-content max-content;
  justify-content: start;
  gap: 12px;
}
.how-actions > * { justify-content: center; }
.how-actions > :nth-child(1) { grid-area: 1 / 1; }
.how-actions > :nth-child(2) { grid-area: 2 / 1; }
.how-actions > :nth-child(3) { grid-area: 2 / 2; }

/* The hero's buttons are the site's button: 13/22 padding, the body's type,
   a 1 px border (transparent where there is no outline). Everything that
   stands on its own matches them -- the small pills inside the portfolio
   cards keep their own scale, they belong to the card. */
.how-actions .cta-solid { padding: 13px 22px; border: 1px solid transparent; }

.how-actions .back-link { border-color: var(--line); }

/* The one loud button outside the hero. */
.cta-solid {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 24px;
  background: var(--teal);
  border-radius: 999px;
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.15s ease;
}

.cta-solid:hover { background: #0fc4b2; transform: translateY(-1px); }
.cta-solid:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; }

@media (max-width: 560px) {
  .step { grid-template-columns: 1fr; gap: 2px; padding-left: 22px; }
  .step-time { flex-direction: row; align-items: baseline; gap: 8px; }
  .step-number { font-size: 1.5rem; }
  .step-unit { margin-top: 0; }
}

/* ----------------------------------------------------------------- facts */

/* A white card straddling the bottom edge of the hero: three facts, a rule,
   and one line under them. It overlaps the navy by half its own height, which
   is what ties the dark band to the page below it. */
.facts {
  position: relative;
  z-index: 1;
  max-width: var(--max-width);
  margin: -54px auto 0;
  padding: 26px clamp(20px, 3vw, 34px);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
}

.facts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 22px 34px;
}

.fact {
  padding-left: 16px;
  border-left: 3px solid var(--teal);
}

.fact-label {
  margin: 0 0 4px;
  color: var(--slate);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.fact-value {
  margin: 0;
  color: var(--navy);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.35;
}

.facts-note {
  margin: 22px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--slate);
  font-size: 0.9rem;
}

/* The line under the facts card. */
.creed {
  max-width: var(--max-width);
  margin: clamp(38px, 6vw, 62px) auto clamp(30px, 5vw, 52px);
  padding: 0 20px;
  text-align: center;
}

.creed-words,
.creed-line { display: block; }

/* Display size, a few steps under the hero's title: the four words set in
   Unbounded at the h1's size would run past 1600 px and wrap (Dave asked for
   as big as it fits, 13 October 2026). */
.creed-words {
  color: var(--navy);
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.15rem, 2.9vw, 2.05rem);
  letter-spacing: 0.08em;
  line-height: 1.25;
}

.creed-line {
  margin-top: 12px;
  color: var(--slate);
  font-size: clamp(1.05rem, 1.9vw, 1.35rem);
}

/* ------------------------------------------------------------------ page */

main { flex: 1; }

.page {
  max-width: var(--text-width);
  margin: 0 auto;
  padding: clamp(40px, 6vw, 68px) 20px clamp(56px, 8vw, 92px);
}

.page-wide { max-width: var(--max-width); }

.page h1 {
  margin: 0 0 18px;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  letter-spacing: -0.02em;
  line-height: 1.08;
  text-wrap: balance;
}

.page h2 {
  margin: 44px 0 14px;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.22rem, 2.4vw, 1.55rem);
  letter-spacing: -0.01em;
  line-height: 1.22;
  text-wrap: balance;
}

.page h2:first-of-type { margin-top: 30px; }
.page h3 { margin: 28px 0 10px; font-weight: 600; font-size: 1.05rem; }

.page p { margin: 0 0 16px; }
.page p a { color: var(--teal-ink); font-weight: 600; text-decoration-color: rgba(16,179,163,0.45); text-underline-offset: 3px; }
.page p a:hover { color: var(--navy); }

.page p.legal-meta {
  margin-bottom: 26px;
  color: var(--slate);
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.page ul:not(.page-links) { margin: 0 0 18px; padding-left: 22px; }
.page ul:not(.page-links) li { margin-bottom: 8px; line-height: 1.65; }
.page ul:not(.page-links) li::marker { color: var(--teal); }
.page ul:not(.page-links) li p { margin: 0; }

.page ol { margin: 0 0 18px; padding-left: 22px; }
.page ol li { margin-bottom: 8px; line-height: 1.65; }
.page ol li::marker { color: var(--teal-ink); font-weight: 600; }
.page ol li p { margin: 0; }

.page code {
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--cloud);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
}

/* The legal landing page's list of documents. */
.page ul.page-links { display: grid; gap: 10px; margin: 26px 0 0; padding: 0; list-style: none; }
.page ul.page-links li { margin: 0; }

.page ul.page-links a {
  display: block;
  padding: 16px 20px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.page ul.page-links a:hover { border-color: var(--teal); transform: translateX(3px); }

/* ---------------------------------------------------------------- tables */

.page table {
  width: 100%;
  margin: 0 0 24px;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  font-size: 0.95rem;
}

.page table td { padding: 12px 16px; border-bottom: 1px solid var(--line); vertical-align: top; line-height: 1.55; }
.page table tr:last-child td { border-bottom: 0; }
.page table tr:first-child td { background: var(--cloud); color: var(--navy); font-weight: 600; }

@media (max-width: 560px) {
  .page table, .page table tbody, .page table tr, .page table td { display: block; width: 100%; }
  .page table { border: 0; }
  .page table tr { margin-bottom: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
  .page table td { border-bottom: 1px solid var(--line); }
  .page table td:last-child { border-bottom: none; }
}

/* ------------------------------------------------------------- portfolio */

/* The page behind the cards: cloud rather than paper white, so the navy cards
   have something to sit on. */
main.tinted { background: var(--cloud); }

.apps-subtitle {
  margin: -6px 0 22px;
  color: var(--teal-ink);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.portfolio-switch {
  display: inline-flex;
  gap: 4px;
  padding: 5px;
  margin: 0 0 28px;
  background: var(--cloud);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.portfolio-switch button {
  padding: 9px 22px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--slate);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.portfolio-switch button:hover { color: var(--navy); }
.portfolio-switch button[aria-selected="true"] { background: var(--navy); color: var(--white); }
.portfolio-switch .count { margin-left: 8px; opacity: 0.55; font-variant-numeric: tabular-nums; }

/* Only the open tab takes up room, so what follows -- the back button --
   stands the same distance under two cards as under four (Dave, 13 October
   2026). The tabs sit above the cards and do not move when you switch. */
.app-grid[hidden] { display: none; }

.app-grid {
  display: grid;
  /* auto-fill, not auto-fit: a tab with two cards keeps the same column width
     as the one with four, instead of stretching them across the row. */
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 22px;
  align-content: start;
}

/* Reversed, like the hero (Dave, 13 October 2026): white cards on a white
   page left the portfolio flat, and the buttons inside them were the only
   dark thing on the screen. Navy cards put the apps on the brand's own
   background and let the buttons read the way they do on the home page. */
.app-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px;
  background: var(--card);
  border: 1px solid var(--card-line);
  border-radius: var(--radius);
  color: var(--navy);
  box-shadow: var(--shadow);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.app-card:hover { transform: translateY(-3px); border-color: rgba(16,179,163,0.55); box-shadow: var(--shadow-lift); }

.app-card-head { display: flex; align-items: center; gap: 14px; }

/* A white tile under every icon: it holds the five icons to one shape, and
   on the darker cards it was what kept Fornado's mark and KTCLO's crest from
   disappearing. Kept on the tinted card, where it also lifts them off it. */
.app-icon {
  width: 54px;
  height: 54px;
  padding: 5px;
  background: var(--white);
  border-radius: 14px;
  object-fit: contain;
}

.app-card-title { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }

.app-name { margin: 0; font-family: var(--f-display); font-weight: 600; font-size: 1.02rem; letter-spacing: -0.01em; }
.app-short { margin: 0; font-weight: 600; font-size: 1rem; line-height: 1.45; }
.app-desc { margin: 0; color: var(--slate); font-size: 0.95rem; line-height: 1.6; }
.app-desc em { font-style: italic; }

.app-store-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: auto; padding-top: 4px; }
.app-legal-row { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 16px; border-top: 1px solid var(--card-line); }

/* The portfolio in the manner of the other pages (Dave, 14 October 2026).
   White page, the same text column as Contact and How it works, and the
   same rail with a teal dot per entry as the timeline. Each app or site is
   one wide card on that rail: its icon large on the left, name in the
   display face with the status beside it, text and buttons to the right.
   Everything here is scoped to .portfolio-rows, so removing that class from
   the page puts the grid of tiles back. */
.portfolio-rows .app-grid {
  grid-template-columns: 1fr;
  gap: 22px;
  padding-left: 26px;
  border-left: 2px solid var(--line);
}

.portfolio-rows .app-card {
  position: relative;
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: 12px 24px;
  padding: 26px;
  background: var(--white);
  border-color: var(--line);
}

.portfolio-rows .app-card::before {
  content: "";
  position: absolute;
  left: -34px;
  top: 34px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 4px var(--white);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.portfolio-rows .app-card:hover { transform: translateX(4px); }
.portfolio-rows .app-card:hover::before {
  transform: translateX(-4px) scale(1.5);
  box-shadow: 0 0 0 3px var(--white), 0 0 14px 7px rgba(16, 179, 163, 0.55);
}

/* The head dissolves into the card's grid: the icon takes the left column
   for the card's whole height, the title starts the right one. */
.portfolio-rows .app-card-head { display: contents; }
.portfolio-rows .app-icon {
  grid-column: 1;
  grid-row: 1 / span 5;
  width: 84px;
  height: 84px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 20px;
}
.portfolio-rows .app-card > :not(.app-card-head),
.portfolio-rows .app-card-title { grid-column: 2; }

.portfolio-rows .app-card-title { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.portfolio-rows .app-name { font-size: 1.3rem; }
.portfolio-rows .app-short { font-size: 1.05rem; }
.portfolio-rows .app-store-row { margin-top: 6px; }
.portfolio-rows .app-legal-row { border-top-color: var(--line); }

@media (max-width: 560px) {
  .portfolio-rows .app-grid { padding-left: 20px; }
  .portfolio-rows .app-card { display: flex; padding: 20px; }
  .portfolio-rows .app-card::before { left: -28px; }
  .portfolio-rows .app-card-head { display: flex; }
  .portfolio-rows .app-icon { width: 60px; height: 60px; padding: 6px; border-radius: 16px; }
  .portfolio-rows .app-card-title { flex-direction: column; align-items: flex-start; }
  .portfolio-rows .app-name { font-size: 1.12rem; }
}

/* --------------------------------------------------------- status badges */

.app-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.status-info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 0.6rem;
  opacity: 0.7;
}

.status-live { background: rgba(16, 179, 163, 0.16); color: var(--teal-ink); }
.status-testing { background: rgba(11, 21, 38, 0.08); color: var(--navy); }
.status-development { background: rgba(90, 101, 119, 0.14); color: var(--slate); }
.status-idea { background: rgba(154, 166, 184, 0.2); color: var(--slate); }

/* The popup behind a status badge. */
.status-dialog {
  width: min(560px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
}

.status-dialog::backdrop { background: rgba(11, 21, 38, 0.45); }
.status-dialog-inner { padding: 26px; }

.status-dialog h2 {
  margin: 0 0 14px;
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: -0.01em;
}

.status-dialog form { margin-top: 18px; text-align: right; }

.status-dialog-close {
  padding: 10px 20px;
  background: var(--navy);
  border: 0;
  border-radius: 999px;
  color: var(--white);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.status-dialog-close:hover { background: var(--teal-ink); }

.stage-list { margin: 0; padding-left: 20px; }
.stage { margin-bottom: 12px; }
.stage p { margin: 4px 0 0; color: var(--slate); font-size: 0.93rem; }
.stage.current { font-weight: 600; }

/* --------------------------------------------------------------- buttons */

.store-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: var(--navy);
  border-radius: 999px;
  color: var(--white);
  text-decoration: none;
  transition: background 0.15s ease, transform 0.15s ease;
}

.store-btn:hover { background: var(--teal-ink); transform: translateY(-1px); }
.store-btn svg { width: 18px; height: 18px; flex: none; }
.store-btn .store-btn-lines { display: flex; flex-direction: column; line-height: 1.15; }
.store-btn .store-btn-eyebrow { font-size: 0.58rem; font-weight: 600; letter-spacing: 0.1em; opacity: 0.75; }
.store-btn .store-btn-name { font-size: 0.92rem; font-weight: 600; white-space: nowrap; }

/* "Coming soon": an outline rather than a grey fill, so it reads as a button
   that is not ready instead of one that failed to load. */
.store-btn.disabled {
  background: transparent;
  border: 1px dashed #b9c3d1;
  color: #8b96a8;
  cursor: default;
}

.store-btn.disabled .store-btn-eyebrow { opacity: 1; }

/* "Back to Apps" and friends: the same pill as everywhere else, so a way out
   of a legal page is a button rather than a line of blue text. */
/* `.page p` sets paragraph margins and outranks a bare class, so this has to
   name the paragraph too -- without it the button sat flush under whatever
   came before. */
.page p.back-row, .back-row { margin: var(--button-gap) 0 0; }

/* After the two portraits, which end at different heights, the button needs
   more air under them than after a paragraph. */
/* `~`, not `+`: the script that joins the portraits sits between them. */
.page .founders ~ .back-row { margin-top: var(--button-gap); }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* The site's one button size, the same as the hero's (13 October 2026). */
  padding: 13px 22px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--navy);
  font-weight: 600;
  font-size: 1.0625rem;
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.back-link:hover {
  border-color: var(--teal);
  color: var(--teal-ink);
  transform: translateX(-2px);
}

.back-link:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; }

.legal-btn {
  padding: 7px 14px;
  background: var(--white);
  border: 1px solid var(--card-line);
  border-radius: 999px;
  color: var(--slate);
  font-size: 0.82rem;
  font-weight: 600;
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.legal-btn:hover { border-color: var(--teal); color: var(--teal-ink); }

/* ----------------------------------------------------------------- forms */

.contact-email { margin: 0 0 30px; }

/* The address is the one thing to do on this page, so it is a button like
   every other one on the site -- not a line of blue text (Dave, 13 October
   2026). The envelope is an icon, the address itself is written in by the
   script in the footer. */
.contact-email .email-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 22px;
  background: var(--navy);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--white);
  font-weight: 600;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.15s ease;
}

.contact-email .email-btn svg { width: 19px; height: 19px; flex: none; }
.contact-email .email-btn:hover { background: var(--teal-ink); transform: translateY(-1px); }
.contact-email .email-btn:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; }

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 28px;
  background: var(--cloud);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.form-row.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.form-field { display: flex; flex-direction: column; gap: 7px; }

.form-field label {
  color: var(--slate);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.form-field input, .form-field textarea {
  padding: 13px 15px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--navy);
  font: inherit;
}

.form-field input:focus, .form-field textarea:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px rgba(16, 179, 163, 0.18);
}

.form-field textarea { min-height: 150px; resize: vertical; }
.field-error { margin: 0; color: #b4231f; font-size: 0.85rem; }

.form-banner {
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  background: rgba(16, 179, 163, 0.12);
  color: var(--teal-ink);
  font-weight: 600;
}

.form-banner-error { background: rgba(180, 35, 31, 0.1); color: #b4231f; }

.btn-submit {
  align-self: flex-start;
  padding: 14px 30px;
  background: var(--navy);
  border: 0;
  border-radius: 999px;
  color: var(--white);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}

.btn-submit:hover { background: var(--teal-ink); transform: translateY(-1px); }

/* The honeypot: there for robots, never for people. */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.email-link-inline { color: var(--teal-ink); font-weight: 600; text-underline-offset: 3px; }
.email-link-inline:hover { color: var(--navy); }

/* ------------------------------------------------------------- founders */

.founders {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 26px;
  max-width: 560px;
  margin: 44px 0 0;
  transition: gap 0.45s ease, padding 0.45s ease;
}

.founder { margin: 0; }

/* Both tiles draw the same photograph: apart, each is a square framed on one
   face; joined, they are its left and right half, flush, with the picture
   running across the seam. Everything that differs between the two states --
   the gap, the shape of the tiles, the framing, the corners -- is a property
   that animates, so one slides into the other (Dave, 13 October 2026). */
.founder-shot {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  background-image: url('/assets/team/founders.jpg');
  /* Zoomed in far enough that the two squares take nothing from the middle
     of the photograph -- otherwise the same flowerpot stands behind both of
     them (Dave, 13 October 2026). The joined state drops back to life size. */
  background-size: auto 165%;
  background-position: var(--focus);
  background-repeat: no-repeat;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-size 0.45s ease, background-position 0.45s ease,
    border-radius 0.45s ease;
}

.founder-shot:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; }

/* Closing the gap would make each column 13 px wider, and the tiles are
   square, so they would grow as much in height and push the page down. The
   block takes that 26 px back as padding instead. */
.founders.joined {
  gap: 0;
  padding-inline: 13px;
}

/* The tiles stay square in both states, so nothing under them moves when the
   two join: the picture is laid across the pair at twice a tile's width and
   its own proportions, which trims a little off the top and bottom. Matching
   the picture's shape instead would make the pair taller than the squares and
   push the rest of the page down. */
.founders.joined .founder-shot { background-size: 200% auto; }

.founders.joined .founder-left {
  background-position: left center;
  border-right-width: 0;
  border-radius: var(--radius) 0 0 var(--radius);
}

.founders.joined .founder-right {
  background-position: right center;
  border-left-width: 0;
  border-radius: 0 var(--radius) var(--radius) 0;
}

.founder figcaption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-top: 14px;
  text-align: center;
}

.founder-name {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
}

.founder-role {
  color: var(--slate);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* One line under the portraits, centred on the pair rather than on the
   page, and it changes with them (Dave, 13 October 2026): apart, who stands
   behind SMDS; joined into one photograph, the motto. Both lines share one
   grid cell and cross-fade over the same 0.45 s as the photographs, so the
   swap moves nothing below it. */
.founders-note {
  display: grid;
  align-items: center;
  max-width: 560px;
  margin-top: 34px;
  text-align: center;
}
.page .founders-note p {
  grid-area: 1 / 1;
  margin: 0;
  transition: opacity .45s ease, visibility .45s;
}
.page .founders-note .founders-motto {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
  opacity: 0;
  visibility: hidden;
}
.page .founders-note .founders-behind { color: var(--slate); font-size: 0.92rem; }
.page .founders.joined ~ .founders-note .founders-motto { opacity: 1; visibility: visible; }
.page .founders.joined ~ .founders-note .founders-behind { opacity: 0; visibility: hidden; }

/* The claim under the swapping line: always there, centred on the portraits
   like the line above it. */
.page p.founders-claim {
  max-width: 560px;
  margin: 26px 0 0;
  font-family: var(--f-display);
  /* The motto's type exactly, so the two read as a pair. */
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
  text-align: center;
}

/* ---------------------------------------------------------------- footer */

footer {
  padding: 36px 20px;
  background: var(--navy);
  color: var(--mist);
  font-size: 0.9rem;
}

footer a { color: var(--white); text-decoration-color: rgba(255,255,255,0.35); text-underline-offset: 3px; }
footer a:hover { color: var(--teal); }

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  max-width: var(--max-width);
  margin: 0 auto;
}

.footer-inner img { height: 28px; width: auto; }
.footer-links { display: flex; flex-wrap: wrap; gap: 18px; }
.footer-links a { color: var(--mist); font-weight: 600; text-decoration: none; }
.footer-links a:hover { color: var(--teal); }

/* ----------------------------------------------------------------- small */

@media (max-width: 640px) {
  body { font-size: 16px; }

  /* The header is a logo, four language links and a menu button on one line;
     at full size that is ~410 px and a phone is 360. Everything shrinks
     together rather than the button being pushed off the screen edge
     (Dave, on a 6.9" phone, 13 October 2026). */
  header { gap: 10px; padding: 12px 16px; }
  .brand { min-width: 0; }
  .brand img { height: 24px; max-width: 100%; }
  .header-right { gap: 8px; }
  .lang-switcher { gap: 0; }
  .lang-switcher a { padding: 5px 5px; font-size: 0.7rem; letter-spacing: 0.04em; }
  .menu-toggle { width: 40px; height: 40px; padding: 0 10px; }
  .menu-panel { right: 16px; left: 16px; min-width: 0; }
  .hero .lockup { gap: 14px; }
  .hero .icon { width: 44px; height: 44px; }
  .cta-list { grid-template-columns: 1fr; }
  .facts { margin: -36px 16px 0; padding: 22px; }
  .fact { padding-left: 14px; }
  .form-row.two-col { grid-template-columns: 1fr; }
  .footer-inner { flex-direction: column; align-items: flex-start; }
}

/* Narrower still (small Android phones, iPhone SE): the language links lose
   their last millimetres of padding before anything leaves the screen. */
@media (max-width: 380px) {
  .brand img { height: 22px; }
  .lang-switcher a { padding: 5px 3px; font-size: 0.66rem; }
}
