/* ==========================================================
   COLLINS MUIGAI — PORTFOLIO
   The site is drawn as a route map: one green line runs down
   the page, sections are its stations, each project is its own
   coloured line, and the WhatsApp chat is the end of the line.

   1. Design tokens (change colours, type and spacing here)
   2. Base and browser surfaces
   3. Layout, the route rail and stations
   4. Buttons and shared bits
   5. Header and navigation
   6. Hero and route strip
   7. About, Skills
   8. Projects
   9. Secure Development
   10. Contact, dock, footer
   11. Project page
   12. Motion
   ========================================================== */

/* ==========================================================
   1. DESIGN TOKENS
   Dark mode follows the visitor's system setting automatically.
   ========================================================== */
:root {
  --ground: #fbfbfa;
  --ground-2: #f3f4f2;
  --ink: #15171c;
  --ink-2: #474d59;
  --ink-3: #69707d;
  --rule: #e2e4e7;
  --rule-strong: #c9cdd3;
  --rail-idle: #d9ddda;

  /* Route lines. Green is Collins's own line and the WhatsApp action;
     red, amber and blue are the project lines, in that order. */
  --line-green: #0b7a4b;
  --line-green-deep: #08603b;
  --line-red: #d23f27;
  --line-amber: #d68f00;
  --line-blue: #2457d6;
  --on-green: #ffffff;
  --green-tint: #dcefe5;

  --font: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --text-sm: 0.875rem;
  --text-base: 1.0625rem;
  --text-lg: 1.1875rem;

  --gutter: 16px;
  --max-width: 1200px;
  --header-height: 64px;
  --section-pad: clamp(72px, 10vw, 136px);

  /* The route rail: --rail-x is where the 6px line sits inside the container's
     padding, --rail-space is how far content is set in to clear it. */
  --rail-w: 6px;
  --rail-x: 11px;
  --rail-space: 44px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #0d1015;
    --ground-2: #13171e;
    --ink: #eceef1;
    --ink-2: #b1b8c3;
    --ink-3: #8e97a5;
    --rule: #242a33;
    --rule-strong: #353c47;
    --rail-idle: #262d36;

    --line-green: #2fbf7c;
    --line-green-deep: #5fd69c;
    --line-red: #ff6a4f;
    --line-amber: #f4b13b;
    --line-blue: #6c95ff;
    --on-green: #04140c;
    --green-tint: #123224;
  }
}

:root[data-theme="dark"] {
  --ground: #0d1015;
  --ground-2: #13171e;
  --ink: #eceef1;
  --ink-2: #b1b8c3;
  --ink-3: #8e97a5;
  --rule: #242a33;
  --rule-strong: #353c47;
  --rail-idle: #262d36;
  --line-green: #2fbf7c;
  --line-green-deep: #5fd69c;
  --line-red: #ff6a4f;
  --line-amber: #f4b13b;
  --line-blue: #6c95ff;
  --on-green: #04140c;
  --green-tint: #123224;
}

@media (min-width: 600px) {
  :root { --gutter: 24px; }
}

@media (min-width: 1024px) {
  :root {
    --gutter: 40px;
    --rail-space: 104px;
  }
}

/* ==========================================================
   2. BASE AND BROWSER SURFACES
   ========================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-height) + 16px);
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--rule-strong) var(--ground);
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: 1.6;
  font-feature-settings: "tnum" 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  caret-color: var(--line-green);
}

::selection {
  background: var(--line-green);
  color: var(--on-green);
}

img,
svg {
  display: block;
  max-width: 100%;
}

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.1;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

ul, ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

:focus-visible {
  outline: 3px solid var(--line-green);
  outline-offset: 3px;
  border-radius: 4px;
}

main:focus {
  outline: none;
}

.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;
}

.skip-link {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--ground);
  font-weight: 650;
  border-radius: 999px;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform 0.2s var(--ease-out);
}

.skip-link:focus {
  transform: none;
}

/* Content still to be replaced with the real thing (see README). */
.placeholder,
[data-placeholder="true"] {
  outline: 2px dashed var(--line-amber);
  outline-offset: 3px;
}

.empty-state {
  padding: 24px 0;
  color: var(--ink-3);
  border-top: 1px solid var(--rule);
}

/* ==========================================================
   3. LAYOUT, THE ROUTE RAIL AND STATIONS
   ========================================================== */
.container {
  width: 100%;
  max-width: calc(var(--max-width) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* A section's padding lives on its container so the rail runs edge to edge
   and joins the next section's rail without a gap. */
.railed {
  --rail-color: var(--line-green);
  position: relative;
  padding-block: var(--section-pad);
  padding-left: calc(var(--gutter) + var(--rail-space));
}

.railed::before,
.railed::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--gutter) + var(--rail-x));
  width: var(--rail-w);
}

.railed::before {
  background: var(--rail-idle);
}

/* The green part grows as you scroll (js/shared.js sets --fill). */
.railed::after {
  background: var(--rail-color);
  transform: scaleY(var(--fill, 1));
  transform-origin: top;
}

/* The page's own colour comes from the route; sections differ only in rhythm. */
.section--alt {
  background: var(--ground-2);
}

/* Station markers: a ring on the rail beside every section heading,
   centred on the heading's first line. */
.section__title,
.project-page__title,
.project-page__heading {
  position: relative;
}

.section__title::before,
.project-page__title::before,
.project-page__heading::before {
  content: "";
  position: absolute;
  top: calc(0.5em - 14px);
  left: calc(var(--rail-x) + var(--rail-w) / 2 - var(--rail-space) - 14px);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 6px solid var(--rail-color, var(--line-green));
  background: var(--ground);
  z-index: 1;
  transition: background-color 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}

.section--alt .section__title::before {
  background: var(--ground-2);
}

/* Reached: the station fills in. */
.railed.is-reached .section__title::before,
.railed.is-reached .project-page__title::before,
.railed.is-reached .project-page__heading::before {
  background: var(--rail-color, var(--line-green));
  box-shadow: inset 0 0 0 4px var(--ground);
}

.section--alt .railed.is-reached .section__title::before {
  box-shadow: inset 0 0 0 4px var(--ground-2);
}

.section__header {
  max-width: 760px;
  margin-bottom: clamp(40px, 6vw, 72px);
}

.section__title {
  font-size: clamp(2.125rem, 5vw, 3.5rem);
  font-weight: 760;
  font-stretch: 115%;
  letter-spacing: -0.03em;
  line-height: 1;
}

.section__title--large {
  font-size: clamp(2.5rem, 7vw, 5rem);
  font-stretch: 120%;
  letter-spacing: -0.035em;
}

.section__intro {
  margin-top: 20px;
  max-width: 60ch;
  font-size: var(--text-lg);
  color: var(--ink-2);
}

/* ==========================================================
   4. BUTTONS AND SHARED BITS
   ========================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 26px;
  border: 2px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-size: 1rem;
  font-weight: 650;
  line-height: 1.1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 0.2s var(--ease-out),
    border-color 0.2s var(--ease-out),
    color 0.2s var(--ease-out),
    transform 0.2s var(--ease-out);
}

.btn:active {
  transform: translateY(1px);
}

.btn--small {
  min-height: 42px;
  padding: 0 18px;
  font-size: 0.9375rem;
}

.btn__icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linejoin: round;
}

/* Green is the WhatsApp line: used only for getting in touch. */
.btn--go {
  background: var(--line-green);
  color: var(--on-green);
}

.btn--go:hover {
  background: var(--line-green-deep);
}

.btn--primary {
  background: var(--ink);
  color: var(--ground);
}

.btn--primary:hover {
  background: var(--ink-2);
}

.btn--secondary {
  border-color: var(--ink);
  color: var(--ink);
}

.btn--secondary:hover {
  background: var(--ink);
  color: var(--ground);
}

.btn--placeholder {
  border: 2px dashed var(--rule-strong);
  color: var(--ink-3);
  cursor: default;
}

/* Technology names: stops in a line, each with its own ring, so a wrapped
   line never starts with a stray separator. */
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
}

.tag-list li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9375rem;
  font-weight: 560;
  color: var(--ink-2);
}

.tag-list li::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 2px solid var(--line, var(--ink-3));
}

.arrow {
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  vertical-align: -0.12em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.25s var(--ease-out);
}

a:hover > .arrow,
a:hover .contact-card__action .arrow {
  transform: translateX(3px);
}

.site-footer__top:hover > .arrow {
  transform: translateY(-3px);
}

.back-link:hover > .arrow {
  transform: translateX(-3px);
}

.text-accent {
  text-decoration: underline;
  text-decoration-color: var(--line-green);
  text-decoration-thickness: 0.16em;
  text-underline-offset: 0.14em;
  text-decoration-skip-ink: none;
}

/* ==========================================================
   5. HEADER AND NAVIGATION
   ========================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--ground) 90%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--rule);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: var(--header-height);
}

.nav__logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-weight: 760;
  font-stretch: 115%;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.nav__logo-mark svg {
  width: 28px;
  height: 28px;
}

.mark-line {
  fill: var(--line-green);
}

.mark-stop {
  fill: var(--ground);
  stroke: var(--ink);
  stroke-width: 4;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 32px;
}

.nav__link {
  position: relative;
  display: inline-block;
  padding: 8px 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-2);
  text-decoration: none;
  transition: color 0.2s var(--ease-out);
}

.nav__link:hover,
.nav__link.is-active {
  color: var(--ink);
}

/* The current section shows as a station dot under its link. */
.nav__link::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  background: var(--line-green);
  transform: scale(0);
  transition: transform 0.3s var(--ease-out);
}

.nav__link.is-active::after {
  transform: scale(1);
}

.nav__toggle {
  display: none;
  position: relative;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.nav__toggle-bar,
.nav__toggle-bar::before,
.nav__toggle-bar::after {
  position: absolute;
  left: 11px;
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.3s var(--ease-out), opacity 0.2s;
}

.nav__toggle-bar {
  top: 21px;
}

.nav__toggle-bar::before,
.nav__toggle-bar::after {
  content: "";
  left: 0;
}

.nav__toggle-bar::before { top: -7px; }
.nav__toggle-bar::after { top: 7px; }

.nav__toggle[aria-expanded="true"] .nav__toggle-bar { background: transparent; }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar::before { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar::after { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 859px) {
  .nav__toggle {
    display: block;
  }

  .nav__links {
    position: absolute;
    top: var(--header-height);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px var(--gutter) 24px;
    background: var(--ground);
    border-bottom: 1px solid var(--rule);
    box-shadow: 0 24px 40px -24px rgb(0 0 0 / 0.25);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-8px);
    transition:
      opacity 0.25s var(--ease-out),
      transform 0.25s var(--ease-out),
      visibility 0s linear 0.25s;
  }

  .nav__links.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition-delay: 0s;
  }

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

  .nav__links li:last-child {
    border-bottom: 0;
    padding-top: 16px;
  }

  .nav__link {
    display: block;
    padding: 14px 0;
    font-size: 1.125rem;
  }

  .nav__link::after {
    left: auto;
    right: 4px;
    top: 50%;
    bottom: auto;
    margin: -3.5px 0 0;
  }

  .nav__cta {
    width: 100%;
    min-height: 48px;
  }
}

/* ==========================================================
   6. HERO AND ROUTE STRIP
   ========================================================== */
.hero {
  position: relative;
  overflow: hidden;
  padding-top: clamp(32px, 4.5vw, 56px);
}

.hero__grid {
  display: grid;
  gap: 8px;
}

.hero__content {
  padding-bottom: clamp(32px, 5vw, 72px);
}

.hero__title {
  font-size: clamp(3.25rem, 10.5vw, 6rem);
  font-weight: 800;
  font-stretch: 125%;
  letter-spacing: -0.04em;
  line-height: 0.9;
}

.hero__role {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
  font-size: var(--text-base);
  font-weight: 650;
  color: var(--ink-2);
}

.hero__role::before {
  content: "";
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 3px solid var(--line-green);
}

.hero__lead {
  margin-top: 22px;
  max-width: 30ch;
  font-size: clamp(1.375rem, 2.6vw, 2rem);
  font-weight: 560;
  line-height: 1.22;
  letter-spacing: -0.015em;
}

.hero__summary {
  margin-top: 20px;
  max-width: 58ch;
  color: var(--ink-2);
}

.hero__focus {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  margin-top: 20px;
  max-width: 62ch;
  font-size: 0.9375rem;
  font-weight: 620;
}

/* Every item gets its own stop dot, so a wrapped line never starts with a stray separator. */
.hero__focus li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.hero__focus li::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 2px solid var(--ink-3);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

.hero__more {
  margin-top: 16px;
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.hero__more a {
  color: var(--ink);
  font-weight: 600;
}

/* The portrait stands with its feet on the route line. */
.hero__figure {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  pointer-events: none;
}

.hero__photo {
  width: auto;
  height: clamp(300px, 80vw, 380px);
  /* Down to the bottom edge of the line in the strip below. */
  margin-bottom: -17px;
}

@media (min-width: 900px) {
  .hero__grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
    align-items: end;
    gap: 40px;
  }

  .hero__content {
    padding-bottom: clamp(40px, 4.5vw, 64px);
  }

  .hero__figure {
    justify-content: flex-end;
  }

  .hero__photo {
    height: clamp(440px, 42vw, 580px);
    margin-right: clamp(0px, 3vw, 48px);
  }
}

/* The strip map: a straight line with every stop on this page. */
.strip {
  position: relative;
  padding-bottom: 0;
}

/* Labels hang below the line at 45 degrees, as on an in-vehicle strip map.
   The bottom padding is the room they need; the right padding is the room
   the last label needs to run out past the terminus. */
.strip__scroll {
  padding: 0 var(--strip-tail, 150px) var(--strip-drop, 210px) 0;
}

.strip__line {
  display: flex;
}

.strip__stop {
  --stop: var(--line-green);
  position: relative;
  flex: 1 1 0;
  min-width: 0;
}

/* Each stop draws the segment to the next stop. */
.strip__stop::before {
  content: "";
  position: absolute;
  top: 11px;
  left: 14px;
  width: 100%;
  height: var(--rail-w);
  background: var(--line-green);
  border-radius: 3px;
  transform-origin: left;
}

.strip__stop:last-child {
  flex: 0 0 auto;
}

.strip__stop:last-child::before {
  content: none;
}

/* The first stop also drops a line down into the About section's rail. */
.strip__stop:first-child::after {
  content: "";
  position: absolute;
  top: 14px;
  left: 11px;
  width: var(--rail-w);
  height: calc(100% + var(--strip-drop, 210px));
  background: var(--line-green);
}

.strip__stop a {
  position: relative;
  z-index: 1;
  display: block;
  width: 28px;
  text-decoration: none;
}

.strip__dot {
  display: block;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 6px solid var(--stop);
  background: var(--ground);
  transition: transform 0.3s var(--ease-out), background-color 0.3s var(--ease-out);
}

/* Project stops are interchanges with their own line colour. */
.strip__stop--project .strip__dot {
  box-shadow: 0 0 0 3px var(--ground), 0 0 0 5px var(--stop);
  border-width: 7px;
}

.strip__label {
  position: absolute;
  top: 40px;
  left: 18px;
  transform: rotate(45deg);
  transform-origin: 0 0;
  white-space: nowrap;
  font-size: 0.9375rem;
  font-weight: 650;
  line-height: 1.25;
}

/* The rail drops straight down from the first stop, so its label starts
   clear of the line (a rotated label's height leans back to the left). */
.strip__stop:first-child .strip__label {
  left: 34px;
}

.strip__label small {
  margin-left: 8px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-3);
}

/* The terminus note only shows where the page is wide enough to hold it. */
@media (max-width: 1199px) {
  .strip__label small {
    display: none;
  }
}

@media (max-width: 599px) {
  .strip {
    --strip-tail: 72px;
    --strip-drop: 180px;
  }

  .strip__label {
    top: 36px;
    left: 14px;
    font-size: 0.8125rem;
  }

  .strip__stop:first-child .strip__label {
    left: 30px;
  }
}

.strip__stop a:hover .strip__dot,
.strip__stop a:focus-visible .strip__dot {
  transform: scale(1.18);
  background: var(--stop);
}

.strip__stop a:hover .strip__label {
  text-decoration: underline;
  text-decoration-color: var(--stop);
  text-decoration-thickness: 2px;
}

/* The terminus: a heavier, filled station. */
.strip__stop--end .strip__dot {
  width: 36px;
  height: 36px;
  margin-top: -4px;
  background: var(--line-green);
  box-shadow: inset 0 0 0 4px var(--ground);
}

/* ==========================================================
   7. ABOUT, SKILLS
   ========================================================== */
.about__grid {
  display: grid;
  gap: 48px 72px;
}

.about__grid .section__header {
  margin-bottom: 0;
}

.about__text {
  display: grid;
  gap: 20px;
  max-width: 64ch;
  color: var(--ink-2);
  font-size: var(--text-lg);
  line-height: 1.65;
}

.about__text p:first-child {
  color: var(--ink);
  font-size: clamp(1.25rem, 2.2vw, 1.5rem);
  font-weight: 540;
  line-height: 1.45;
  letter-spacing: -0.01em;
}

/* The map legend: what each kind of work looks like. */
.about__focus {
  border-top: 2px solid var(--ink);
}

.about__focus li {
  display: grid;
  grid-template-columns: 28px 1fr;
  column-gap: 16px;
  padding: 18px 0;
  border-bottom: 1px solid var(--rule);
}

.about__focus-icon {
  grid-row: span 2;
  width: 28px;
  height: 28px;
  fill: none;
  stroke: var(--line-green);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}


.about__focus h3 {
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.3;
}

.about__focus p {
  margin-top: 4px;
  font-size: 0.9375rem;
  color: var(--ink-2);
}

@media (min-width: 960px) {
  .about__grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }

  .about__grid .section__header {
    grid-column: 1 / -1;
  }

  .about__focus {
    align-self: start;
  }
}

/* Skills read as a line index: the category, then its stops. */
.skills-grid {
  border-top: 2px solid var(--ink);
}

.skill-group {
  display: grid;
  gap: 10px;
  padding: 22px 0;
  border-bottom: 1px solid var(--rule);
}

.skill-group__title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 1.0625rem;
  font-weight: 720;
  font-stretch: 110%;
  line-height: 1.3;
}

.skill-group__title::before {
  content: "";
  flex: none;
  width: 22px;
  height: 6px;
  border-radius: 3px;
  background: var(--line-green);
}


.skill-group .tag-list li {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--ink);
}

.skill-group .tag-list li::before {
  border-color: var(--ink-3);
}

@media (min-width: 760px) {
  .skill-group {
    grid-template-columns: 240px 1fr;
    gap: 24px;
    align-items: baseline;
  }
}

/* ==========================================================
   8. PROJECTS
   ========================================================== */
.project-list {
  display: grid;
  gap: clamp(88px, 11vw, 152px);
}

.project {
  --line: var(--line-red);
  display: grid;
  gap: 32px;
}

.project__text {
  min-width: 0;
}

/* Each project branches off the trunk on its own coloured line. */
.project__name {
  position: relative;
  font-size: clamp(2rem, 4.4vw, 3.25rem);
  font-weight: 780;
  font-stretch: 115%;
  letter-spacing: -0.03em;
  line-height: 1;
}

.project__name::before {
  content: "";
  position: absolute;
  top: 0.38em;
  left: calc(var(--rail-x) + var(--rail-w) - var(--rail-space));
  width: calc(var(--rail-space) - var(--rail-x) - var(--rail-w) - 12px);
  height: var(--rail-w);
  border-radius: 0 3px 3px 0;
  background: var(--line);
}

/* The interchange where the branch leaves the trunk. */
.project__name::after {
  content: "";
  position: absolute;
  top: calc(0.38em - 11px);
  left: calc(var(--rail-x) + var(--rail-w) / 2 - var(--rail-space) - 14px);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 6px solid var(--line);
  background: var(--ground);
  box-shadow: 0 0 0 3px var(--ground);
}

.project__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-top: 16px;
  font-size: var(--text-sm);
  font-weight: 620;
  color: var(--ink-2);
}

.project__badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--ink);
}

.project__badge::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--line);
}

.project__summary {
  margin-top: 20px;
  max-width: 54ch;
  font-size: var(--text-lg);
  line-height: 1.55;
}

.project__detail {
  margin-top: 28px;
}

.project__detail h4 {
  margin-bottom: 10px;
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--ink);
}

.project__detail p {
  max-width: 58ch;
  color: var(--ink-2);
}

/* Key features as stops along the project's line. */
.project__stops {
  position: relative;
  display: grid;
  gap: 2px;
}

.project__stops::before {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 7px;
  width: 4px;
  border-radius: 2px;
  background: var(--line);
}

.project__stops li {
  position: relative;
  padding: 4px 0 4px 32px;
  font-weight: 560;
}

.project__stops li::before {
  content: "";
  position: absolute;
  top: 9px;
  left: 1px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 4px solid var(--line);
  background: var(--ground);
}

.project__stops .project__more {
  font-weight: 500;
  color: var(--ink-3);
}

.project__stops .project__more::before {
  border-color: var(--rule-strong);
  border-style: dotted;
}

.project .tag-list {
  margin-top: 28px;
}

.project__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
}

/* The screenshot, framed by a hairline rule. */
.project__media {
  min-width: 0;
}

.project__shot {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--ground-2);
}

.project__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.9s var(--ease-out);
}

a.project__shot:hover img {
  transform: scale(1.025);
}

.project__shot--empty {
  display: grid;
  place-items: center;
  color: var(--ink-3);
  font-weight: 600;
}

.project__caption {
  margin-top: 12px;
  max-width: 70ch;
  font-size: var(--text-sm);
  color: var(--ink-3);
}

@media (min-width: 960px) {
  .project {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 56px;
    align-items: start;
  }

  .project__media {
    position: sticky;
    top: calc(var(--header-height) + 32px);
  }
}

/* ==========================================================
   9. SECURE DEVELOPMENT
   ========================================================== */
.entry-list {
  border-top: 2px solid var(--ink);
}

.notice {
  display: grid;
  gap: 16px;
  padding: 32px 0;
  border-bottom: 1px solid var(--rule);
}

.notice__title {
  font-size: clamp(1.375rem, 2.4vw, 1.75rem);
  font-weight: 720;
  font-stretch: 110%;
  letter-spacing: -0.02em;
}

.notice__type {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: var(--text-sm);
  font-weight: 620;
  color: var(--ink-2);
}

.notice__type::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 3px solid var(--line, var(--line-green));
}

.notice__body > p {
  max-width: 62ch;
  color: var(--ink-2);
}

.notice__body .tag-list {
  margin-top: 18px;
}

.notice__body .project__actions {
  margin-top: 20px;
}

@media (min-width: 860px) {
  .notice {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: 48px;
  }
}

/* ==========================================================
   10. CONTACT, DOCK, FOOTER
   ========================================================== */

/* The end of the line: the rail stops at the Contact station. */
/* js/main.js measures --rail-end so the line stops at the WhatsApp terminus. */
.section--contact .railed::before,
.section--contact .railed::after {
  bottom: auto;
  height: var(--rail-end, calc(var(--section-pad) + 3rem));
}

.contact-list li:has(.contact-card--whatsapp) {
  position: relative;
}

/* The line turns into the WhatsApp panel and ends at a filled terminus. */
.contact-list li:has(.contact-card--whatsapp)::before,
.contact-list li:has(.contact-card--whatsapp)::after {
  content: "";
  position: absolute;
  z-index: 1;
}

.contact-list li:has(.contact-card--whatsapp)::before {
  top: calc(56px - var(--rail-w) / 2);
  left: calc(var(--rail-x) + var(--rail-w) / 2 - var(--rail-space));
  width: calc(var(--rail-space) - var(--rail-x));
  height: var(--rail-w);
  background: var(--line-green);
}

.contact-list li:has(.contact-card--whatsapp)::after {
  top: 36px;
  left: calc(var(--rail-x) + var(--rail-w) / 2 - var(--rail-space) - 20px);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 8px solid var(--line-green);
  background: var(--line-green);
  box-shadow: inset 0 0 0 5px var(--ground);
}

.contact-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0 32px;
}

.contact-card {
  display: grid;
  grid-template-columns: 24px 1fr;
  column-gap: 14px;
  align-content: start;
  height: 100%;
  padding: 22px 0 24px;
  border-top: 2px solid var(--ink);
  text-decoration: none;
}

.contact-card__icon {
  grid-row: span 3;
  width: 24px;
  height: 24px;
  margin-top: 2px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.contact-card__label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-3);
}

.contact-card__value {
  margin-top: 2px;
  font-size: 1.125rem;
  font-weight: 680;
  overflow-wrap: anywhere;
}

.contact-card__action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  font-size: var(--text-sm);
  font-weight: 650;
  color: var(--line-green);
}

.contact-card:hover .contact-card__value {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--line-green);
}

/* WhatsApp: the terminus panel, the one large field of green on the page. */
.contact-list li:has(.contact-card--whatsapp) {
  grid-column: 1 / -1;
  margin-bottom: 32px;
}

.contact-card--whatsapp {
  grid-template-columns: 1fr;
  gap: 6px;
  padding: clamp(28px, 5vw, 56px);
  border: 0;
  border-radius: 4px;
  background: var(--line-green);
  color: var(--on-green);
  transition: background-color 0.25s var(--ease-out);
}

.contact-card--whatsapp:hover {
  background: var(--line-green-deep);
}

.contact-card--whatsapp .contact-card__icon {
  grid-row: auto;
  width: 40px;
  height: 40px;
  margin-bottom: 18px;
  stroke-width: 1.6;
}

/* The number and the button already say WhatsApp; the label stays for screen readers. */
.contact-card--whatsapp .contact-card__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

.contact-card--whatsapp .contact-card__value {
  font-size: clamp(1.5rem, 6.4vw, 3.75rem);
  white-space: nowrap;
  font-weight: 800;
  font-stretch: 118%;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

.contact-card--whatsapp .contact-card__action {
  display: inline-flex;
  justify-self: start;
  align-items: center;
  gap: 8px;
  margin-top: 24px;
  padding: 14px 24px;
  border-radius: 999px;
  background: var(--on-green);
  color: var(--line-green);
  font-size: var(--text-base);
  transition: transform 0.25s var(--ease-out);
}

.contact-card--whatsapp:hover .contact-card__value {
  text-decoration: none;
}

.contact-card--whatsapp:hover .contact-card__action {
  transform: translateX(6px);
}

/* Phones: a WhatsApp button that stays within thumb reach. */
.dock {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 40;
  display: none;
}

.dock__btn {
  width: 100%;
  box-shadow: 0 12px 28px -10px rgb(0 0 0 / 0.45);
}

@media (max-width: 719px) {
  .dock {
    display: block;
    visibility: hidden;
    transform: translateY(calc(100% + 24px));
    transition:
      transform 0.4s var(--ease-out),
      visibility 0s linear 0.4s;
  }

  .dock.is-shown {
    visibility: visible;
    transform: none;
    transition-delay: 0s;
  }
}

.site-footer {
  border-top: 1px solid var(--rule);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px 32px;
  padding-block: 36px 40px;
}

.footer-contact__list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
}

.footer-contact__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  text-decoration: none;
  font-weight: 560;
  transition: color 0.2s var(--ease-out);
}

.footer-contact__link:hover {
  color: var(--ink);
}

.footer-contact__icon {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.site-footer__top {
  font-weight: 650;
  color: var(--ink);
  text-decoration: none;
}

.site-footer__top:hover {
  text-decoration: underline;
}

@media (max-width: 719px) {
  /* Leave room for the WhatsApp dock. */
  .site-footer__inner {
    padding-bottom: 96px;
  }
}

/* ==========================================================
   11. PROJECT PAGE
   ========================================================== */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin-top: 24px;
  font-weight: 650;
  font-size: var(--text-sm);
  color: var(--ink-2);
  text-decoration: none;
}

.back-link:hover {
  color: var(--ink);
  text-decoration: underline;
}

.project-page .railed {
  --rail-color: var(--line, var(--line-green));
  padding-top: clamp(32px, 5vw, 56px);
}

.project-page__title {
  font-size: clamp(2.5rem, 7vw, 5rem);
  font-weight: 800;
  font-stretch: 120%;
  letter-spacing: -0.035em;
  line-height: 0.95;
}

.project-page__title::before {
  top: calc(0.475em - 18px);
  width: 36px;
  height: 36px;
  left: calc(var(--rail-x) + var(--rail-w) / 2 - var(--rail-space) - 18px);
  border-width: 8px;
}

.project-page__header .project-type {
  display: block;
  margin-top: 18px;
  font-weight: 650;
  color: var(--ink-2);
}

.project-page__lead {
  margin-top: 20px;
  max-width: 56ch;
  font-size: clamp(1.1875rem, 2vw, 1.4375rem);
  line-height: 1.5;
}

.project-page__header .card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
}

.project-page__section {
  margin-top: clamp(64px, 8vw, 104px);
}

.project-page__heading {
  margin-bottom: 24px;
  font-size: clamp(1.625rem, 3vw, 2.25rem);
  font-weight: 760;
  font-stretch: 112%;
  letter-spacing: -0.025em;
}

.project-page__heading::before {
  top: calc(0.55em - 14px);
}

.project-page__section > p + p {
  margin-top: 16px;
}

.project-page__section > p {
  max-width: 66ch;
  color: var(--ink-2);
  font-size: var(--text-lg);
}

.project-page__gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr));
  gap: 32px 24px;
}

.project-page__shot {
  margin: 0;
}

.project-page__shot a {
  display: block;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--ground-2);
}

.project-page__shot img {
  width: 100%;
  height: auto;
  max-height: 640px;
  object-fit: contain;
  transition: transform 0.9s var(--ease-out);
}

.project-page__shot a:hover img {
  transform: scale(1.02);
}

.project-page__shot figcaption {
  margin-top: 12px;
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.project-page__shot-empty {
  padding: 48px 24px;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius);
  color: var(--ink-3);
  text-align: center;
}

.project-page__layout {
  display: grid;
  gap: 48px 72px;
}

.project-page__aside {
  align-self: start;
  padding-top: 20px;
  border-top: 2px solid var(--ink);
}

.project-page__aside-title {
  margin-bottom: 16px;
  font-size: var(--text-base);
  font-weight: 720;
}

@media (min-width: 960px) {
  .project-page__layout {
    grid-template-columns: minmax(0, 8fr) minmax(0, 3fr);
  }

  .project-page__aside {
    position: sticky;
    top: calc(var(--header-height) + 32px);
    margin-top: clamp(64px, 8vw, 104px);
  }
}

/* Features as stops along the project's line. */
.feature-list {
  position: relative;
  display: grid;
  gap: 24px;
}

.feature-list::before {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 7px;
  width: 4px;
  border-radius: 2px;
  background: var(--line);
}

.feature-list__item {
  position: relative;
  padding-left: 36px;
}

.feature-list__item::before {
  content: "";
  position: absolute;
  top: 4px;
  left: 1px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 4px solid var(--line);
  background: var(--ground);
}

.feature-list__title {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.35;
}

.feature-list__item p {
  margin-top: 6px;
  max-width: 64ch;
  color: var(--ink-2);
}

/* The project page's closing call. */
.closing-call {
  display: grid;
  gap: 16px;
  justify-items: start;
  margin-top: clamp(80px, 10vw, 128px);
}

/* The end of the line: a filled green terminus beside the call. */
.closing-call__title {
  position: relative;
}

.closing-call__title::before {
  content: "";
  position: absolute;
  top: calc(0.5em - 20px);
  left: calc(var(--rail-x) + var(--rail-w) / 2 - var(--rail-space) - 20px);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 8px solid var(--line-green);
  background: var(--line-green);
  box-shadow: inset 0 0 0 5px var(--ground);
}

.closing-call__title {
  max-width: 20ch;
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  font-weight: 780;
  font-stretch: 115%;
  letter-spacing: -0.03em;
}

.closing-call__text {
  max-width: 52ch;
  color: var(--ink-2);
  font-size: var(--text-lg);
}

.closing-call__text a {
  color: var(--ink);
  font-weight: 650;
}

.closing-call .btn {
  margin-top: 8px;
}

/* Not-found state reuses the title and lead. */
.project-page .railed > .btn {
  margin-top: 28px;
}

.project-page .railed > .project-page__lead {
  margin-bottom: 0;
}

/* ==========================================================
   12. MOTION
   One authored moment (the strip drawing itself), the rail that
   follows the scroll, and a quiet rise as content arrives.
   ========================================================== */
@keyframes draw-x {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes draw-y {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

@keyframes stop-in {
  from { transform: scale(0.4); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  .strip__stop::before {
    animation: draw-x 0.5s var(--ease-out) both;
    animation-delay: calc(300ms + var(--i, 0) * 110ms);
  }

  .strip__stop:first-child::after {
    transform-origin: top;
    animation: draw-y 0.6s var(--ease-out) both;
    animation-delay: 200ms;
  }

  .strip__dot {
    animation: stop-in 0.5s var(--ease-out) both;
    animation-delay: calc(240ms + var(--i, 0) * 110ms);
  }

  .reveal {
    opacity: 0;
  }

  .reveal.is-visible {
    animation: rise 0.8s var(--ease-out) both;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }
}
