/* TITECH v3 · surfaces.css: owned by the work order listed in work-orders/DESIGN-SPEC.md §1. */
/* The dark/light rhythm, the background decoration and one shared photo grade (DESIGN-SPEC §5, §5.1, §5.2). */

/* Decoration values (§5.1). WO-06 reuses them on the hero: the grid, glow and grain go in background-image,
   --deco-grid-size in background-size and --deco-grid-mask in mask-image. The grain is opaque grey noise centred on
   50% (sRGB), the one level at which an overlay blend leaves the base colour alone and only adds texture. Used at the
   spec's .035 opacity it changed 4 pixels in 14,400 by one level, so the ::after below runs it at .5 (about 1.4 levels).
   On the lighter banner navy (owner, 2026-09-22) the same overlay reads as speckle at .5 and lifts its brightest specks by a
   fifth, enough to take --ctx-muted under 4.5:1, so it runs at the spec's .035 there, the home banner's own value. */
:root {
  --deco-grid: linear-gradient(90deg, var(--grid-line) 1px, transparent 1px), linear-gradient(var(--grid-line) 1px, transparent 1px);
  --deco-grid-size: 64px 64px;
  --deco-grid-mask: radial-gradient(ellipse 80% 60% at 70% 0%, #000 0%, transparent 75%);
  --deco-glow: radial-gradient(600px circle at 85% 10%, rgb(76 141 255 / .12), transparent 60%);
  --deco-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Arabic: the glow and the grid fade sit at the inline-end, which is the left. */
[dir="rtl"] {
  --deco-grid-mask: radial-gradient(ellipse 80% 60% at 30% 0%, #000 0%, transparent 75%);
  --deco-glow: radial-gradient(600px circle at 15% 10%, rgb(76 141 255 / .12), transparent 60%);
}

/* Dark contexts (§5, the exact selector list). The context variables sit in :where() so they carry no specificity
   and never get in the way of a rule that loads later. Owner (2026-09-22): the dark sections are the banner's navy, and a
   card on them is a glass layer, translucent white over the navy and its aurora, rather than a darker hole. */
:where(.hero, .page-hero, .solutions-section, .section:has(.industry-list), .cta-band, .site-footer, .section-navy) {
  /* The spectrum becomes the brandbook's 40% tints of the same four colours (WO-22a). Raw Deep Navy in a gradient
     is invisible on a Deep Navy banner, and the 60% step left Plum Shadow at 3.4:1 on the flat navy, which the
     aurora would take under 3:1. At 40% the four sit between 4.7 and 6.5:1 on #26436C and keep an even lightness,
     so the kicker rule, the card accent lines and the hero's gradient line read as one family.
     --c-spec-* and the two gradients are restated, not just the channels: a custom property substitutes its var()s
     where it is DECLARED, so a token built on :root keeps :root's channels however deep it is inherited. */
  /* Architect (integration): the 40% tints passed contrast but washed the gradient out — the headline lost the
     colour that carries the brand. These keep each brand hue's saturation and lift only lightness, to the point
     where each still measures >= 3.2:1 on the lightest pixel of the lit banner (#35527B). Measured, not chosen. */
  --c-spec-1-rgb: 216 146 159; /* Rosewood     lifted · #D8929F · 3.23:1 */
  --c-spec-2-rgb: 188 153 194; /* Plum Shadow  lifted · #BC99C2 · 3.20:1 */
  --c-spec-3-rgb: 134 167 213; /* Deep Navy    lifted · #86A7D5 · 3.22:1 */
  --c-spec-4-rgb: 140 199 150; /* Sage Green   lifted · #8CC796 · 4.06:1 */
  --c-spec-1: rgb(var(--c-spec-1-rgb));
  --c-spec-2: rgb(var(--c-spec-2-rgb));
  --c-spec-3: rgb(var(--c-spec-3-rgb));
  --c-spec-4: rgb(var(--c-spec-4-rgb));
  --g-spectrum: linear-gradient(90deg, rgb(var(--c-spec-1-rgb)) 0%, rgb(var(--c-spec-2-rgb)) 34%, rgb(var(--c-spec-3-rgb)) 67%, rgb(var(--c-spec-4-rgb)) 100%);
  --g-spectrum-soft: linear-gradient(90deg, rgb(var(--c-spec-1-rgb) / .45), rgb(var(--c-spec-2-rgb) / .45), rgb(var(--c-spec-3-rgb) / .45), rgb(var(--c-spec-4-rgb) / .45));
  --ctx-bg: var(--c-banner);
  --ctx-surface: rgb(255 255 255 / .05);
  --ctx-surface-hover: rgb(255 255 255 / .09);
  --ctx-heading: #F4F7FB;
  --ctx-body: #D3DCE8;
  --ctx-muted: #BCC8D5;
  --ctx-line: rgb(255 255 255 / .12);
  --ctx-line-strong: rgb(255 255 255 / .24);
  --ctx-link: var(--c-signal-soft);
  --ctx-tint: rgb(255 255 255 / .05);
  --ctx-focus: var(--c-signal-soft); /* WO-19 integration: --c-signal measured 2.6 to 3.2:1 on the lighter banner navy and aurora (WO-19a's check) */
  --ctx-field-border: rgb(255 255 255 / .45);
}
/* Legacy rules read --muted and --line for text and rules, so inside a dark section they follow the context too. */
.hero, .page-hero, .solutions-section, .cta-band, .site-footer, .section-navy {
  --muted: var(--ctx-muted);
  --line: var(--ctx-line);
  color: var(--ctx-body);
  background-color: var(--c-banner);
}
/* The industries section on its own, so a browser without :has() still gets everything above. */
.section:has(.industry-list) {
  --muted: var(--ctx-muted);
  --line: var(--ctx-line);
  color: var(--ctx-body);
  background-color: var(--c-banner);
}
/* Footer (owner, 2026-09-22): the calm form of the same navy, with no aurora hotspots. WO-22a: one shade of the
   brandbook ladder below the CTA band (Deep Navy +30%), so the two still separate without a line. */
.site-footer {
  --ctx-bg: #1B2F4C;
  background-color: #1B2F4C;
  background-image: var(--bg-footer);
}

/* Light contexts (§5). A light section takes its surface from --section-bg: porcelain, unless it touches another light
   section (below) or carries a legacy .section-* class. The legacy sage fills and white sections all resolve here. */
.section:not(.solutions-section, .section-navy, :has(.industry-list)) {
  background-color: var(--section-bg, var(--ctx-bg));
}
.section-soft, .section-tinted {
  --section-bg: var(--c-porcelain);
  background-color: var(--section-bg);
}
.section-white {
  --section-bg: var(--c-white);
  background-color: var(--section-bg);
}
/* Where light sections touch they alternate, porcelain then white, so the boundary reads without a line. Every selector
   below is one white position: the 2nd, 4th, 6th or 8th light section of an unbroken run (a run starts at a light
   section that doesn't follow another). They carry no specificity, so the .section-* classes above still win. */
:where(
  .section:not(.solutions-section, .section-navy, :has(.industry-list)):not(.section:not(.solutions-section, .section-navy, :has(.industry-list)) + *) + .section:not(.solutions-section, .section-navy, :has(.industry-list)),
  .section:not(.solutions-section, .section-navy, :has(.industry-list)):not(.section:not(.solutions-section, .section-navy, :has(.industry-list)) + *) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)),
  .section:not(.solutions-section, .section-navy, :has(.industry-list)):not(.section:not(.solutions-section, .section-navy, :has(.industry-list)) + *) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)),
  .section:not(.solutions-section, .section-navy, :has(.industry-list)):not(.section:not(.solutions-section, .section-navy, :has(.industry-list)) + *) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list)) + .section:not(.solutions-section, .section-navy, :has(.industry-list))
) {
  --section-bg: var(--c-white);
}
/* The same boundary loses the legacy hairline. Dark sections keep theirs: --line is --ctx-line there, a faint line. */
.section + .section:not(.solutions-section, .section-navy, :has(.industry-list)) {
  border-block-start-width: 0;
}
/* The timeline dots cut the rule behind them with a ring in the section's own colour (legacy: hard-coded sage). */
.timeline-item::before {
  box-shadow: 0 0 0 5px var(--section-bg, var(--ctx-bg));
}

/* Dark decoration (§5.1): the grid fades out from the top on ::before, the grain lies over everything on ::after and
   the light is the section's own background. Two pseudo-elements can't carry all three: the grid needs a mask,
   the grain a blend mode, and the light must have neither. The footer takes the grid only. .hero is WO-06's.
   Owner (2026-09-22): the light is the banner's navy and aurora (--bg-banner-section, tokens.css), in place of the ink
   background and its single glow. The page hero takes the banner's page form, --bg-banner-page (end of file). */
:where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .site-footer, .section-navy) {
  position: relative;
  isolation: isolate;
}
.solutions-section, .section-navy {
  background-image: var(--bg-banner-section);
}
.section:has(.industry-list) {
  background-image: var(--bg-banner-section);
}
:where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .site-footer, .section-navy)::before,
:where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .section-navy)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
:where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .site-footer, .section-navy)::before {
  background-image: var(--deco-grid);
  background-size: var(--deco-grid-size);
  -webkit-mask-image: var(--deco-grid-mask);
  mask-image: var(--deco-grid-mask);
}
:where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .section-navy)::after {
  background-image: var(--deco-grain);
  mix-blend-mode: overlay;
  opacity: .035;
}

/* Page heroes: dark, with room for the header, and their visual on the same footing as every other photo. */
.page-hero {
  padding-block: clamp(96px, 12vw, 176px) clamp(64px, 8vw, 120px);
  border-block-end: 1px solid var(--ctx-line);
}
.page-hero-visual {
  border-color: var(--ctx-line);
}
/* The orbit illustration is not a photo: no box, the rings drawn in --ctx-line. Its orbs keep their own fills. */
.page-hero-visual:has(> svg) {
  border-color: transparent;
  background: transparent;
}
.page-hero-visual > svg :is(circle, ellipse, path)[stroke] {
  stroke: var(--ctx-line);
  stroke-opacity: 1;
}
.page-hero-visual > svg ellipse[stroke] {
  stroke: var(--ctx-line-strong);
}
/* The centre disc holds the orbit mark. --ctx-surface is translucent glass now, which would let the spokes show through
   it, so the disc is the brand navy itself: a calm, solid ground under the lit aurora, where the mark's colours stay vivid. */
.page-hero-visual > svg circle[fill="#fff"] {
  fill: var(--c-banner);
  stroke: var(--ctx-line-strong);
}
.page-hero .breadcrumb [aria-current] {
  color: var(--ctx-heading);
}

/* Photo treatment (§5.2): one grade for every photo, cooler, desaturated and darker at the bottom. The spec's starting
   values (.78, 1.06, .94, wash .16, fade .55) left the golden desert shots and the violet server room fighting, so
   saturation, contrast and the navy wash were tuned by eye; brightness and the fade are still the spec's. */
:root {
  --photo-saturate: .62; /* architect: .44 read as grey; .62 keeps the set cohesive and alive */
  --photo-contrast: 1.08;
  --photo-brightness: .94;
  --photo-wash: rgb(37 66 108 / .26);
  --photo-fade: rgb(7 13 24 / .55);
}
.industry-image, .solution-image, .page-hero-visual, .feature-image, .profile-cover, .industry-overview-image {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--r-lg);
  background: var(--ctx-tint);
}
.page-hero-visual {
  border-radius: var(--r-xl);
}
.industry-image img, .solution-image img, .page-hero-visual img, .feature-image img, .profile-cover img, .industry-overview-image img {
  filter: saturate(var(--photo-saturate)) contrast(var(--photo-contrast)) brightness(var(--photo-brightness));
}
:where(.industry-image, .solution-image, .page-hero-visual:has(img), .feature-image, .profile-cover, .industry-overview-image)::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 45%, var(--photo-fade)), var(--photo-wash);
  mix-blend-mode: multiply;
}

/* Industry list on dark: a larger 4:3 image, --ctx-* text and lines, and a hover that lights the row. */
.industry-list {
  border-block-start: 1px solid var(--ctx-line);
}
.industry-row {
  padding-block: clamp(24px, 3vw, 44px);
  border-block-end: 1px solid var(--ctx-line);
}
.industry-image {
  aspect-ratio: 3 / 2; /* architect: shorter rows; the home industries list was 2,500px tall */
}
.industry-body {
  color: var(--ctx-body);
}
.industry-title {
  transition: color var(--dur-fast) var(--ease-out);
}
.industry-image img {
  transition: filter var(--dur-base) var(--ease-out);
}
.industry-list .industry-row:is(:hover, :focus-within) .industry-title {
  color: var(--c-signal-soft);
}
.industry-list .industry-row:is(:hover, :focus-within) .industry-image img {
  --photo-brightness: 1;
}
@media (min-width: 601px) {
  .industry-row { grid-template-columns: 28% minmax(0, 1fr); }
}
@media (min-width: 900px) {
  .industry-row { grid-template-columns: 28% minmax(0, 1fr) auto; }
}

/* CTA band: a dark card with a 1px spectrum border (padding-box over border-box) and the grid. Owner (2026-09-22): inside
   the border it is the banner's navy and aurora. The three padding-box layers are --bg-banner-section's three; the spectrum
   is the last layer and the only one painted under the border. */
.cta-band {
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  background-color: var(--c-banner);
  background-image: var(--bg-banner-section), var(--g-spectrum); /* architect: full spectrum, the CTA's signature line */
  background-origin: padding-box, padding-box, padding-box, border-box;
  background-clip: padding-box, padding-box, padding-box, border-box;
}
/* On phones the band's top padding is about 40px, not a section's 72px, so its two hotspots rise by the difference and stay
   in the padding, clear of the kicker. no-repeat keeps the lifted layers from tiling back in at the bottom. */
@media (max-width: 600px) {
  .cta-band {
    background-position: 0 -40px, 0 -40px, 0 0, 0 0;
    background-repeat: no-repeat;
  }
}
.cta-band p, .cta-band .cta-contact p, .cta-contact address {
  color: var(--ctx-body);
}
.cta-band .section-kicker, .cta-band .cta-contact .section-kicker {
  color: var(--ctx-muted);
}
.cta-contact {
  border-color: var(--ctx-line-strong);
}
.cta-contact a {
  color: var(--ctx-heading);
}

/* Footer: --c-ink-900, so it separates from the CTA band above it. */
.site-footer h2, .site-footer h3, .site-footer h4 {
  color: var(--ctx-heading);
}
.site-footer .nav-link {
  color: var(--ctx-body);
}
.site-footer a:hover, .site-footer .nav-link:is(:hover, :focus-visible) {
  color: var(--ctx-heading);
}
.footer-brand .footer-small {
  color: var(--ctx-muted);
}
.footer-bottom {
  border-block-start-color: var(--ctx-line);
  color: var(--ctx-muted);
}

/* Spacing: every section breathes the same, and a section head sits one --space-block above its content. Two
   exceptions where a full section of padding would leave a void: a section that holds only a link (the cross-link under
   the capability grids), and a dark section that follows the dark page hero, which already ends with its own padding. */
.section {
  padding-block: var(--space-section);
}
.section:has(> .shell > .text-link:only-child) {
  padding-block: var(--space-block);
}
.page-hero + :is(.solutions-section, .section-navy, .section:has(.industry-list)) {
  padding-block-start: var(--space-block);
}
.section-head, .why-content .section-head, .faq-section .section-head {
  margin-block-end: var(--space-block);
}

/* Legacy leftovers inside dark sections. components.css (WO-02) restyles all of these and loads later, so at the
   equal specificity used here its rules win; they only keep a dark section legible until then. */
:where(.page-hero, .solutions-section, .section:has(.industry-list), .cta-band, .section-navy) .text-link {
  --link-fill: var(--ctx-tint);
  --link-hover-ink: var(--ctx-heading);
  color: var(--ctx-link);
  border-color: var(--ctx-line-strong);
}
:where(.solutions-section, .section:has(.industry-list), .section-navy) .service-icon {
  color: var(--ctx-heading);
  background: var(--ctx-tint);
}
:where(.solutions-section, .section:has(.industry-list), .section-navy) .service-tags li {
  color: var(--ctx-muted);
  background: transparent;
  border-color: var(--ctx-line);
}
:where(.solutions-section, .section:has(.industry-list), .section-navy) .service-card:is(:hover, :focus-within) {
  background-color: var(--ctx-surface-hover);
  box-shadow: none;
}

/* Print: the legacy print rules force white paper, so the dark sections drop back to the light values and lose the
   decoration. :is() rather than :where() here, so the reset also beats the interim dark block in type.css. */
@media print {
  :is(.hero, .page-hero, .solutions-section, .section:has(.industry-list), .cta-band, .section-navy) {
    --ctx-bg: inherit;
    --ctx-surface: inherit;
    --ctx-surface-hover: inherit;
    --ctx-heading: inherit;
    --ctx-body: inherit;
    --ctx-muted: inherit;
    --ctx-line: inherit;
    --ctx-line-strong: inherit;
    --ctx-link: inherit;
    --ctx-tint: inherit;
  }
  :where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .section-navy)::before,
  :where(.solutions-section, .section:has(.industry-list), .page-hero, .cta-band, .section-navy)::after {
    content: none;
  }
}

/* Architect (WO-05 review): the company-profile cover is a designed graphic, not a photo, so it keeps its own colours. */
.profile-cover img { filter: none; }
.profile-cover::after { content: none; }
.profile-cover { box-shadow: none; } /* WO-04: the legacy shadow popped in after the clip reveal */

/* Owner choice (option C): page banners are brand navy with a soft aurora, a shade brighter at the top than the navy
   sections below. --bg-banner-page is the banner with its hotspots kept off the eyebrow and heading (tokens.css). */
.page-hero { background-color: var(--c-banner); background-image: var(--bg-banner-page); }

/* Why TITECH, reduced to two cards (owner, 2026-09-24: the four repeated the proof band above it). With less text
   the column used to hang at the top of a tall photo, so the pair centres against it and the cards keep their width. */
.why-split:has(.why-grid--pair) { align-items: center; }
@media (min-width: 901px) {
  .why-grid--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 640px; }
}
