/* ==========================================================================
   Epic Web Works, homepage
   Navy / cyan brand palette. Depends on tokens and primitives from app.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Masthead
   -------------------------------------------------------------------------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color var(--base) var(--ease), box-shadow var(--base) var(--ease);
}

.masthead.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: 0 1px 0 var(--line);
}

.masthead__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: 4.75rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 660;
  letter-spacing: -0.018em;
  color: var(--ink);
}

.masthead__nav { display: none; gap: var(--space-5); }
@media (min-width: 1000px) { .masthead__nav { display: flex; } }

.masthead__nav a {
  font-size: var(--text-sm);
  font-weight: 560;
  color: var(--ink-mute);
  padding-block: 0.25rem;
  position: relative;
  transition: color var(--fast) var(--ease);
}

.masthead__nav a::after {
  content: "";
  position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 2px;
  border-radius: var(--r-pill);
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--base) var(--ease-soft);
}

.masthead__nav a:hover { color: var(--ink); }
.masthead__nav a:hover::after { transform: scaleX(1); }

.masthead__end { display: flex; align-items: center; gap: var(--space-4); }
.masthead__end .btn { display: none; }

/* Between 640 and 999px the CTA sits next to the 2.75rem round menu button;
   the default .btn padding makes it visibly taller, so it's matched to the
   same 44px height here. At 1000px+ the menu button is gone and the CTA
   reverts to its normal size. */
@media (min-width: 640px) {
  .masthead__end .btn { display: inline-flex; padding: 0.5rem 1.25rem; }
}
@media (min-width: 1000px) {
  .masthead__end .btn { padding: 0.875rem 1.625rem; }
}

.menu-btn {
  display: flex; flex-direction: column; gap: 4px;
  width: 2.75rem; height: 2.75rem;
  align-items: center; justify-content: center;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--paper);
  cursor: pointer;
}

@media (min-width: 1000px) { .menu-btn { display: none; } }

.menu-btn span {
  display: block; width: 1.125rem; height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform var(--base) var(--ease), opacity var(--fast) var(--ease);
}

.menu-btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-btn[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.drawer {
  display: grid; grid-template-rows: 0fr; overflow: hidden;
  background: var(--paper);
  transition: grid-template-rows var(--base) var(--ease);
}

.drawer.is-open { grid-template-rows: 1fr; border-bottom: 1px solid var(--line); }
@media (min-width: 1000px) { .drawer { display: none; } }

.drawer__inner { min-height: 0; }
.drawer__list { padding-block: var(--space-3) var(--space-6); }

.drawer__list a {
  display: block; padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 1.375rem; font-weight: 620; letter-spacing: -0.018em;
  color: var(--ink);
  transition: color var(--fast) var(--ease), background-color var(--fast) var(--ease);
}

/* The primary mobile nav rows get real tap feedback: without this the only
   confirmation a visitor gets that their tap landed is the page changing.
   Full-bleed background, matching the row's own full-width divider. */
.drawer__list a:active:not(.btn) { color: var(--cyan); background: var(--sand); }

/* .drawer__list a above sets display:block, padding, and a border for the
   plain nav rows; both selectors have equal class-count specificity, so
   without these resets the CTA link inherits that block layout instead of
   the pill button it's meant to be. */
.drawer__list .btn {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: var(--space-5); width: 100%;
  padding: 0.875rem 1.625rem;
  border-bottom: none;
  color: var(--paper);
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(2.5rem, 1rem + 6vw, 5.5rem) clamp(3rem, 2rem + 4vw, 5.5rem);
  position: relative;
  isolation: isolate;
  /* The decorative arc bleeds past the right edge on purpose; clip it here so it
     cannot widen the page and cause horizontal scroll. */
  overflow: hidden;
}

.hero__arc {
  width: clamp(22rem, 30vw, 40rem);
  height: clamp(22rem, 30vw, 40rem);
  top: -12%;
  right: -8%;
}

.hero__top {
  display: grid;
  gap: var(--space-8);
  align-items: center;
}

@media (min-width: 980px) {
  .hero__top { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: clamp(2rem, 1rem + 4vw, 4.5rem); }
}

.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.4375rem 0.9375rem 0.4375rem 0.5rem;
  border-radius: var(--r-pill);
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
  font-size: var(--label-sm);
  font-weight: 620;
  color: var(--ink-soft);
  margin-bottom: var(--space-5);
}

.hero__title { max-width: 15ch; }

.hero__actions { margin-top: var(--space-7); }

.hero__meta {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
}

.hero__meta-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-sm);
  color: var(--ink-mute);
}

.hero__meta-item svg { width: 1.0625rem; height: 1.0625rem; color: var(--cyan); flex-shrink: 0; }

/* Illustrated panel replacing a stock "team photo": a warm, abstract
   composition built from the arc motif rather than a generic dashboard
   mockup or a fabricated photo of people who do not exist. */
.brief-panel {
  position: relative;
  border-radius: var(--r-lg);
  background: var(--sand);
  border: 1px solid var(--line);
  padding: var(--space-6);
  overflow: hidden;
}

.brief-panel__arc {
  width: 16rem; height: 16rem;
  bottom: -30%; left: -20%;
}

.brief-panel__eyebrow {
  font-size: var(--label-xs);
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--space-5);
}

.brief-list { display: grid; gap: var(--space-4); }

.brief-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
}

.brief-row:last-child { border-bottom: 0; padding-bottom: 0; }

.brief-row__label {
  display: block;
  font-size: var(--label-xs);
  font-weight: 640;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.brief-row__value {
  display: block;
  margin-top: 0.125rem;
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 610;
  letter-spacing: -0.015em;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Principles (homepage strip under the hero)
   One panel divided by hairlines rather than four separate cards: it reads
   as a single statement of how the studio works, and sits in the slot the
   old figures strip used so the hierarchy below the hero is unchanged.
   -------------------------------------------------------------------------- */

.principles {
  display: grid;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--paper);
  overflow: hidden;
}

@media (min-width: 640px) { .principles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .principles { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.principle {
  padding: var(--space-5) var(--space-5) var(--space-6);
  border-top: 1px solid var(--line);
}

.principle:first-child { border-top: 0; }

@media (min-width: 640px) {
  .principle:nth-child(-n + 2) { border-top: 0; }
  .principle:nth-child(even) { border-left: 1px solid var(--line); }
}

@media (min-width: 1100px) {
  .principle { border-top: 0; }
  .principle + .principle { border-left: 1px solid var(--line); }
}

.principle__icon { display: inline-flex; color: var(--cyan); margin-bottom: var(--space-4); }
.principle__icon svg { width: 1.375rem; height: 1.375rem; }

.principle__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 640;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin-bottom: var(--space-2);
}

.principle__text { font-size: var(--text-sm); line-height: 1.65; color: var(--ink-mute); }

/* --------------------------------------------------------------------------
   Pillars (homepage "What we do")
   -------------------------------------------------------------------------- */

.pillars { display: grid; gap: var(--space-4); counter-reset: none; }

@media (min-width: 760px) { .pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5); } }
@media (min-width: 1200px) { .pillars { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.pillar {
  display: flex;
  flex-direction: column;
  padding: var(--space-6) var(--space-5);
  border-radius: var(--r-md);
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 3px solid var(--line-strong);
  transition: transform var(--base) var(--ease), box-shadow var(--base) var(--ease);
}

.pillar:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }

/* Software leads the offer, so its pillar carries the accent rule. */
.pillar--lead { border-top-color: var(--cyan); }

.pillar__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-5); }

.pillar__num {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 650;
  letter-spacing: 0.02em;
  color: var(--cyan);
}

.pillar .service-card__foot { margin-top: auto; padding-top: var(--space-5); }

/* --------------------------------------------------------------------------
   Software section additions (on the void surface)
   -------------------------------------------------------------------------- */

.capability-row {
  display: grid;
  gap: var(--space-3);
  margin-bottom: var(--space-8);
  padding-bottom: var(--space-8);
  border-bottom: 1px solid var(--line-dark);
}

@media (min-width: 860px) { .capability-row { grid-template-columns: 11rem minmax(0, 1fr); align-items: baseline; } }

.capability-row__label { font-size: var(--label-sm); font-weight: 650; letter-spacing: 0.02em; color: #22d3ee; }

.capability-row__list { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.capability-row__list li {
  padding: 0.4375rem 0.875rem;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, 0.14);
  font-size: var(--text-sm);
  color: #c9d2d9;
}

.product-card { height: 100%; display: flex; flex-direction: column; }

/* .card__list is defined in content.css, which the homepage does not load,
   so the product cards carry their own copy of the bullet treatment. */
.product-card .card__list { display: grid; gap: 0.5rem; margin: var(--space-4) 0 var(--space-6); }
.product-card .card__list li { position: relative; padding-left: 1.25rem; font-size: var(--text-sm); line-height: 1.6; color: #b5bfc7; }
.product-card .card__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 999px;
  background: #22d3ee;
}
.product-card__actions { margin-top: auto; gap: var(--space-5); }
.product-card__actions .link { color: #22d3ee; }

.product-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line-dark);
}

.product-foot p { max-width: 46ch; color: #8993a0; }

/* --------------------------------------------------------------------------
   Case study cover and cards
   The cover is the honest fallback when a case study has no screenshot:
   the project's name and category on the brand surface, not a mock-up.
   Shared by the homepage cards, the case study list and the detail page.
   -------------------------------------------------------------------------- */

.cs-cover {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: clamp(1.5rem, 1rem + 3vw, 3.5rem);
}

.cs-cover__mark { position: absolute; top: clamp(1.5rem, 1rem + 2vw, 2.5rem); left: clamp(1.5rem, 1rem + 3vw, 3.5rem); }
.cs-cover__mark .arc-mark { background: var(--paper); }
.cs-cover__mark .arc-mark::before { background: var(--cyan-bright); }

.cs-cover__title {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.2rem + 4vw, 4.5rem);
  font-weight: 660;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--paper);
}

.cs-cover__meta { position: relative; font-size: var(--text-sm); color: rgba(255, 255, 255, 0.72); }

.cs-cover--card { position: absolute; inset: 0; background: var(--cyan-deep); overflow: hidden; isolation: isolate; }
.cs-cover--card .cs-cover__title { font-size: clamp(1.75rem, 1.2rem + 2.4vw, 3rem); }

.cs-cards { display: grid; gap: var(--space-6); }
@media (min-width: 860px) { .cs-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.cs-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--paper);
  overflow: hidden;
  transition: transform var(--base) var(--ease), box-shadow var(--base) var(--ease);
}

.cs-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lift); }

.cs-card__visual {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  background: var(--void);
  overflow: hidden;
  isolation: isolate;
  border-bottom: 1px solid var(--line);
}

.cs-card__visual img { width: 100%; height: 100%; object-fit: cover; object-position: top; }

.cs-card__body { display: flex; flex-direction: column; flex: 1; padding: var(--space-6); }
.cs-card__meta { font-size: var(--text-sm); color: var(--ink-mute); }

.cs-card__title {
  margin: var(--space-2) 0 var(--space-3);
  font-family: var(--font-display);
  font-size: var(--display-sm);
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.cs-card__text { font-size: var(--text-base); line-height: 1.7; color: var(--ink-soft); margin-bottom: var(--space-5); }
.cs-card__body .link { margin-top: auto; }

/* --------------------------------------------------------------------------
   Figures (case study results)
   -------------------------------------------------------------------------- */

.figures {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

@media (min-width: 860px) { .figures { grid-template-columns: repeat(4, 1fr); gap: var(--space-4); } }

.figure {
  padding: var(--space-5);
  border-radius: var(--r-md);
  background: var(--paper);
  border: 1px solid var(--line);
}

.figure__num {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.25rem);
  font-weight: 660;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.figure__unit { color: var(--cyan); }

.figure__label {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--ink-mute);
}

/* --------------------------------------------------------------------------
   Client strip
   -------------------------------------------------------------------------- */

.trust-label {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--ink-faint);
  margin-bottom: var(--space-6);
}

.ticker {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}

.ticker__track { display: flex; width: max-content; animation: ticker 42s linear infinite; }
.ticker:hover .ticker__track { animation-play-state: paused; }

@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding-inline: clamp(1.25rem, 0.5rem + 2vw, 2.5rem);
  font-family: var(--font-display);
  font-size: clamp(1rem, 0.9rem + 0.6vw, 1.25rem);
  font-weight: 610;
  letter-spacing: -0.015em;
  color: var(--ink-faint);
  white-space: nowrap;
  transition: color var(--base) var(--ease);
}

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

.ticker__item::before {
  content: "";
  width: 1.125rem; height: 1.125rem;
  border-radius: 0.375rem 0.375rem 0.375rem 0.1rem;
  background: currentColor;
  opacity: 0.3;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   Partner badge
   Shares the client-trust section rather than getting a section of its own,
   so one small logo doesn't sit stranded in a full band of empty padding.
   -------------------------------------------------------------------------- */

.partner-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line);
}

.partner-row__label { font-size: var(--text-sm); color: var(--ink-faint); }

.partner-strip__badge {
  display: inline-flex;
  transition: transform var(--fast) var(--ease), opacity var(--fast) var(--ease);
  opacity: 0.9;
}

.partner-strip__badge:hover { transform: translateY(-2px); opacity: 1; }
.partner-strip__badge img { display: block; height: 2.25rem; width: auto; }

/* --------------------------------------------------------------------------
   Services
   -------------------------------------------------------------------------- */

/* Card rows use flex, not grid.
   Every collection here is editable from the admin panel, so item counts
   change without warning and can never be guaranteed to divide evenly into
   the column count. CSS Grid left a short final row hard against the left
   edge with a visible hole beside it. Flex wrap with centred justification
   centres that remainder under the row above, so five cards in a three wide
   layout read as an intentional 3 + 2 rather than a broken row.

   flex-grow is 0 deliberately. Letting the last items grow would stretch two
   cards across a full row and break the visual rhythm of the ones above. */
.grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-5);
}

.grid > * {
  flex: 0 1 100%;
  min-width: 0;
}

/* The 0.02px subtraction is deliberate. A basis of exactly (100% - gaps) / n
   sums to precisely 100%, and sub-pixel rounding at some viewport widths can
   tip that over, wrapping the last card onto its own row. Shaving a hundredth
   of a pixel is invisible and removes the failure mode entirely. */
@media (min-width: 640px) {
  .grid--2 > *,
  .grid--3 > * { flex-basis: calc((100% - var(--space-5)) / 2 - 0.02px); }
}

@media (min-width: 1000px) {
  .grid--3 > * { flex-basis: calc((100% - 2 * var(--space-5)) / 3 - 0.02px); }
}

.service-card { display: flex; flex-direction: column; height: 100%; }
.service-card__foot { margin-top: auto; padding-top: var(--space-5); }

/* --------------------------------------------------------------------------
   Work showcase
   Framed with the arc motif at each corner rather than a dashboard mockup.
   -------------------------------------------------------------------------- */

/* Same reasoning as .grid above. The portfolio holds five published projects
   and the case study list holds two, neither of which divides into three, and
   both counts change as work is added from the panel. */
.work-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6);
}

.work-grid > * { flex: 0 1 100%; min-width: 0; }

@media (min-width: 640px) {
  .work-grid > * { flex-basis: calc((100% - var(--space-6)) / 2 - 0.02px); }
}

@media (min-width: 900px) {
  .work-grid > * { flex-basis: calc((100% - 2 * var(--space-6)) / 3 - 0.02px); }
}

.work-card {
  border-radius: var(--r-lg);
  background: var(--paper);
  border: 1px solid var(--line);
  overflow: hidden;
  transition: transform var(--base) var(--ease), box-shadow var(--base) var(--ease);
}

.work-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lift); }

.work-card__visual {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--cyan-deep);
  overflow: hidden;
  isolation: isolate;
}

.work-card__arc {
  width: 70%; height: 70%;
  bottom: -30%; right: -20%;
  background: rgba(255, 255, 255, 0.08);
}

.work-card__initials {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 2.25rem;
  font-weight: 660;
  letter-spacing: -0.03em;
  color: rgba(255, 255, 255, 0.92);
}

.work-card__body { padding: var(--space-5); }
.work-card__meta { margin-bottom: var(--space-3); }

.work-card__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 640;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin-bottom: var(--space-2);
}

.work-card__text { font-size: var(--text-sm); line-height: 1.65; color: var(--ink-mute); }

/* --------------------------------------------------------------------------
   Industries
   -------------------------------------------------------------------------- */

.industry {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--r-md);
  transition: background-color var(--base) var(--ease);
}

.industry:hover { background: var(--sand); }

.industry__title { font-family: var(--font-display); font-size: var(--text-base); font-weight: 630; color: var(--ink); margin-bottom: 0.1875rem; }
.industry__text { font-size: var(--text-sm); color: var(--ink-mute); line-height: 1.6; }
.industry__link { display: inline-flex; margin-top: var(--space-3); font-size: var(--text-sm); }

/* --------------------------------------------------------------------------
   Process
   -------------------------------------------------------------------------- */

.process-grid {
  display: grid;
  gap: var(--space-5);
}

/* Three across at desktop, not four. There are six process stages, so four
   columns would leave a stranded pair on the second row. */
@media (min-width: 760px) { .process-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .process-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.process-card {
  padding: var(--space-6) var(--space-5);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.process-card__num {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 650;
  color: #22d3ee;
  margin-bottom: var(--space-4);
}

.process-card__title {
  font-family: var(--font-display);
  font-size: 1.1875rem;
  font-weight: 630;
  letter-spacing: -0.018em;
  color: var(--paper);
  margin-bottom: var(--space-2);
}

.process-card__text { font-size: var(--text-sm); line-height: 1.65; color: #8993a0; }

/* Light variant for the standalone Process page, which sits on paper rather
   than inside the homepage's dark section. Without this the cards render
   white-on-white and vanish. */
.process-card--light {
  background: var(--paper);
  border-color: var(--line);
}

.process-card--light .process-card__num { color: var(--cyan); }
.process-card--light .process-card__title { color: var(--ink); }
.process-card--light .process-card__text { color: var(--ink-mute); }

/* --------------------------------------------------------------------------
   Technology
   -------------------------------------------------------------------------- */

.tech-group + .tech-group { margin-top: var(--space-6); }

.tech-group__label {
  font-size: var(--label-sm);
  font-weight: 650;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  margin-bottom: var(--space-3);
}

.tech-chips { display: flex; flex-wrap: wrap; gap: var(--space-3); }

.tech-chip {
  padding: 0.5625rem 1.0625rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: var(--text-sm);
  font-weight: 580;
  color: var(--ink-soft);
  transition: transform var(--fast) var(--ease), border-color var(--base) var(--ease), color var(--base) var(--ease);
}

.tech-chip:hover { transform: translateY(-2px); border-color: var(--cyan); color: var(--cyan); }

/* --------------------------------------------------------------------------
   Testimonials
   -------------------------------------------------------------------------- */

.testimonial { display: flex; flex-direction: column; height: 100%; }
.testimonial__quote { flex: 1; font-size: var(--text-base); line-height: 1.7; color: #c1c9d0; }

.testimonial__stars { display: flex; gap: 0.1875rem; margin-bottom: var(--space-4); color: #22d3ee; }
.testimonial__stars svg { width: 0.9375rem; height: 0.9375rem; }

.testimonial__person {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.testimonial__avatar {
  display: grid; place-items: center;
  width: 2.5rem; height: 2.5rem;
  border-radius: 0.75rem 0.75rem 0.75rem 0.25rem;
  background: rgba(34, 211, 238, 0.14);
  color: #22d3ee;
  font-size: var(--text-sm);
  font-weight: 650;
  flex-shrink: 0;
}

.testimonial__name { font-size: var(--text-sm); font-weight: 630; color: var(--paper); }
.testimonial__role { font-size: var(--label-xs); color: #707b86; margin-top: 0.125rem; }

.testimonial__placeholder-flag {
  display: inline-flex;
  align-self: flex-start;
  margin-bottom: var(--space-4);
  padding: 0.25rem 0.625rem;
  border-radius: var(--r-pill);
  background: rgba(251, 191, 36, 0.14);
  border: 1px solid rgba(251, 191, 36, 0.3);
  color: #fbbf24;
  font-size: var(--label-xs);
  font-weight: 650;
}

/* --------------------------------------------------------------------------
   FAQ
   -------------------------------------------------------------------------- */

.faq { max-width: 50rem; margin-inline: auto; }
.faq__item { border-bottom: 1px solid var(--line); }

.faq__trigger {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  width: 100%;
  padding: var(--space-5) 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 620;
  letter-spacing: -0.015em;
  color: var(--ink);
  transition: color var(--fast) var(--ease);
}

.faq__trigger:hover { color: var(--cyan); }

.faq__icon {
  flex-shrink: 0;
  position: relative;
  width: 1.75rem; height: 1.75rem;
  border-radius: 50%;
  background: var(--sand);
  margin-top: 0.125rem;
  transition: transform var(--fast) var(--ease);
}

/* The icon, not the full-width row, takes the press feedback: scaling an
   edge-to-edge row leaves a visible gap at its sides, which reads as a
   glitch rather than a tap response. */
.faq__trigger:active .faq__icon { transform: scale(0.85); }

.faq__icon::before, .faq__icon::after {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: 0.625rem; height: 1.5px;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform var(--base) var(--ease);
}

.faq__icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq__trigger[aria-expanded="true"] .faq__icon::after { transform: translate(-50%, -50%) rotate(0deg); }

.faq__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--base) var(--ease); }
.faq__panel.is-open { grid-template-rows: 1fr; }
.faq__panel-inner { min-height: 0; overflow: hidden; }

.faq__answer {
  padding-bottom: var(--space-5);
  padding-right: var(--space-8);
  font-size: var(--text-base);
  line-height: 1.72;
  color: var(--ink-mute);
}

/* --------------------------------------------------------------------------
   Closing statement
   -------------------------------------------------------------------------- */

.closer {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--r-lg);
  padding: clamp(2.5rem, 2rem + 4vw, 4.5rem) clamp(1.5rem, 1rem + 4vw, 4rem);
  background: var(--cyan-deep);
  text-align: center;
}

.closer__arc { width: 26rem; height: 26rem; top: -14rem; left: 50%; transform: translateX(-50%); background: rgba(255, 255, 255, 0.06); }

.closer h2 { color: var(--paper); }
.closer__lead { max-width: 36rem; margin: var(--space-4) auto 0; font-size: var(--text-lg); color: #9aa7b0; }
.closer__actions { margin-top: var(--space-7); }

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

.site-footer { background: var(--void); color: #8791a0; padding-block: var(--space-12) var(--space-6); }

.site-footer__top {
  display: grid;
  gap: var(--space-8);
  padding-bottom: var(--space-8);
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
}

@media (min-width: 900px) {
  .site-footer__top { grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr)); gap: var(--space-6); }
}

.site-footer .wordmark { color: var(--paper); }

/* The arc-mark's navy body reads fine on white but disappears against this
   same navy footer. Inverted here: paper body, navy cutout, still the same
   two-colour relationship, just flipped for the dark surface it sits on. */
.site-footer .arc-mark { background: var(--paper); }
.site-footer .arc-mark::before { background: var(--ink); }
.site-footer__blurb { margin-top: var(--space-4); max-width: 26rem; font-size: var(--text-sm); line-height: 1.7; color: #707b86; }

.site-footer__contact { display: grid; gap: 0.25rem; margin-top: var(--space-4); font-size: var(--text-sm); color: #707b86; }
.site-footer__contact a { width: fit-content; color: #c9d2d9; border-bottom: 1px solid rgba(255, 255, 255, 0.2); transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease); }
.site-footer__contact a:hover { color: var(--paper); border-color: currentColor; }

.site-footer__profiles { display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; margin-top: var(--space-4); font-size: var(--text-sm); }
.site-footer__profiles a { color: #c9d2d9; transition: color var(--fast) var(--ease); }
.site-footer__profiles a:hover { color: var(--paper); }

.footer-col__title {
  font-size: var(--label-sm);
  font-weight: 650;
  letter-spacing: 0.02em;
  color: var(--paper);
  margin-bottom: var(--space-4);
}

.footer-col ul { display: grid; gap: 0.6875rem; }
.footer-col a { font-size: var(--text-sm); color: #707b86; transition: color var(--fast) var(--ease); }
.footer-col a:hover { color: var(--paper); }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  padding-top: var(--space-6);
  font-size: var(--text-sm);
  color: #707b86;
}

.footer-badge { display: inline-flex; flex-shrink: 0; opacity: 0.9; transition: opacity var(--fast) var(--ease); }
.footer-badge:hover { opacity: 1; }
.footer-badge img { display: block; height: 1.875rem; width: auto; }

/* --------------------------------------------------------------------------
   Capability panel
   Data graphics driven by live database aggregates, not decorative values.
   Bars fill relative to the leading value so the shape stays readable
   whether the client has five projects or five hundred.
   -------------------------------------------------------------------------- */

.capability {
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 900px) {
  .capability { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2rem, 1rem + 4vw, 4.5rem); }
}

.cap-panel {
  padding: var(--space-6);
  border-radius: var(--r-lg);
  background: var(--paper);
  border: 1px solid var(--line);
}

.section--sand .cap-panel { background: var(--paper); }

.cap-panel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--line);
}

.cap-panel__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 640;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.cap-panel__count {
  font-size: var(--label-sm);
  font-weight: 620;
  color: var(--ink-faint);
}

.bar-list { display: grid; gap: var(--space-4); }

.bar-row { display: grid; gap: 0.5rem; }

.bar-row__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

.bar-row__label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-soft);
}

.bar-row__value {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 660;
  color: var(--cyan);
  font-variant-numeric: tabular-nums;
}

.bar-row__track {
  position: relative;
  height: 0.5rem;
  border-radius: var(--r-pill);
  background: var(--sand-2);
  overflow: hidden;
}

/* Default state is the measured width, so with JS disabled or broken the data
   still reads correctly. Only an active reveal system starts bars at zero and
   animates them in, matching the fail-open rule the reveal layer follows. */
.bar-row__fill {
  position: absolute;
  inset-block: 0;
  left: 0;
  width: var(--bar-share, 0%);
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--cyan), var(--cyan-bright));
  transition: width 1100ms var(--ease-soft);
  transition-delay: var(--bar-delay, 0ms);
}

.js:not(.reveal-off) .bar-row__fill { width: 0; }
.js:not(.reveal-off) .is-revealed .bar-row__fill { width: var(--bar-share, 0%); }

.cap-note {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  font-size: var(--label-xs);
  line-height: 1.6;
  color: var(--ink-faint);
}

/* Summary chips beneath the two panels */
.cap-totals {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-3);
  margin-top: var(--space-6);
}

@media (min-width: 720px) { .cap-totals { grid-template-columns: repeat(4, 1fr); } }

.cap-total {
  padding: var(--space-4);
  border-radius: var(--r-md);
  background: var(--paper);
  border: 1px solid var(--line);
  text-align: center;
}

.cap-total__num {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 660;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.cap-total__label {
  margin-top: 0.375rem;
  font-size: var(--label-xs);
  font-weight: 600;
  color: var(--ink-mute);
}

/* --------------------------------------------------------------------------
   Hero accent arc
   A single stroked arc that draws itself once, echoing the brand mark. This
   is the one piece of motion in the first viewport, so it stays slow and
   quiet rather than announcing itself.
   -------------------------------------------------------------------------- */

.hero__stroke {
  position: absolute;
  top: 8%;
  right: 2%;
  width: clamp(14rem, 22vw, 24rem);
  height: auto;
  z-index: -1;
  pointer-events: none;
  color: var(--cyan);
  opacity: 0.16;
}

@media (max-width: 979px) { .hero__stroke { display: none; } }

/* Base state is fully drawn, so the arc is visible even if the draw script
   never runs. The animation supplies its own hidden starting frame, which
   keeps the effect without ever risking an invisible graphic. */
.hero__stroke path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-dasharray: var(--dash, 1000);
  stroke-dashoffset: 0;
}

.js:not(.reveal-off) .hero__stroke.is-drawn path {
  animation: draw-arc 2600ms var(--ease-soft) both;
}

@keyframes draw-arc {
  from { stroke-dashoffset: var(--dash, 1000); }
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__stroke path { stroke-dashoffset: 0; }
  .js:not(.reveal-off) .hero__stroke.is-drawn path { animation: none; }
  .bar-row__fill { transition: none; }
}
