/* ===== Overrides =====
 * Per the design contract, styles.css is not edited after the initial copy.
 * Any small visual fixes that arise from translating prototypes into Thymeleaf
 * (form validation states, etc.) go here.
 * ============================== */

/* Bootstrap-bound validation states styled in the design's voice. */
.field .form-control.is-invalid,
.field input.is-invalid,
.field textarea.is-invalid,
.field select.is-invalid {
  border-color: #ff5d5d;
  box-shadow: 0 0 0 4px rgba(255, 93, 93, 0.25);
}
.field .invalid-feedback {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #ff8a8a;
  margin-top: 6px;
}

/* Visually hide a field while keeping it accessible to bots (honeypot). */
.hp {
  position: absolute !important;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Saffron focus ring on buttons + links (a11y extension of the form rule). */
.btn:focus-visible,
.nav-cta:focus-visible,
.nav-links a:focus-visible,
.footer a:focus-visible,
.tweak-fab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px var(--saffron-glow);
}

/* =====================================================================
 * Responsive gutters (fix: content touching screen edges on mobile/tablet)
 * ---------------------------------------------------------------------
 * `.wrap` provides the horizontal gutter (32px, 20px on phones). But the
 * `.section` rule and every page's hero rule use the shorthand
 * `padding: <top> 0 <bottom>`, which RESETS the left/right padding to 0.
 * Above 1320px the content still centres (max-width + margin auto), so the
 * bug is invisible on desktop — but on every phone/tablet the text runs
 * edge-to-edge. These two-class selectors out-specify the single-class
 * source rules and re-assert the gutter (longhand, so hero top/bottom
 * padding is preserved).
 * ===================================================================== */
.wrap.section,
.wrap.hero,
.wrap.tc-hero,
.wrap.ds-hero,
.wrap.about-hero,
.wrap.ct-hero,
.wrap.legal-hero {
  padding-left: 32px;
  padding-right: 32px;
}
@media (max-width: 700px) {
  .wrap.section,
  .wrap.hero,
  .wrap.tc-hero,
  .wrap.ds-hero,
  .wrap.about-hero,
  .wrap.ct-hero,
  .wrap.legal-hero {
    padding-left: 20px;
    padding-right: 20px;
  }
}

/* Belt-and-braces: never allow a stray wide child to force a horizontal
 * scrollbar on small screens. (A safety net — the real overflow sources are
 * fixed below so nothing actually gets clipped.) */
html, body { max-width: 100%; overflow-x: hidden; }

/* The ambient background glow (.ambient::after) is positioned at inset:-10%
 * and blurred, so it bleeds ~10% past the viewport on every side. On a phone
 * that ~37px bleed expands the scrollable area / initial containing block,
 * which pushes the fixed topbar (and its hamburger) off the right edge.
 * Clipping the ambient to the viewport keeps the glow but stops the bleed. */
.ambient { overflow: hidden; }

/* =====================================================================
 * Small-phone overflow fixes (≤ ~430px)
 * ---------------------------------------------------------------------
 * The hero headings use a clamp() with a 54px FLOOR. Long single words
 * ("Engineering,", "transformation", "development,") are wider than a narrow
 * phone's content area at 54px and can't break, so they overflow the right
 * edge (and drag the visual layout with them). Scale the hero type down on
 * phones so the longest word always fits, and allow an emergency break.
 * !important is used to beat each page's own inline `.x-hero h1` rule, which
 * loads after this file. Desktop/tablet sizes are untouched.
 * ===================================================================== */
@media (max-width: 560px) {
  .hero h1, .tc-hero h1, .ds-hero h1, .about-hero h1, .ct-hero h1, .legal-hero h1 {
    font-size: clamp(32px, 10vw, 52px) !important;
    overflow-wrap: break-word;
    hyphens: auto;
  }
  /* The home hero wraps each line in <span class="line"><span> for its rise
   * animation; the inner span is display:inline-block, which shrink-wraps to
   * its text on ONE line and won't break — so "Engineering for the world."
   * overflowed the phone and expanded the whole scroll area (dragging the
   * fixed topbar hamburger off-screen with it). Cap it at the line width so
   * the text wraps; the rise animation (translateY on the span) still works. */
  /* NOTE: the home hero's line-mask fix lives in home.html's own <style>
   * block — that stylesheet loads after this file, so an equal-specificity
   * rule here would lose. See the "phones: release the line mask" block there. */
  /* Footer wordmark "growinture." has a 72px floor; its text ink overflows a
   * phone (adding a phantom horizontal scroll). Scale it down to fit. */
  .footer .big-mark { font-size: clamp(38px, 12vw, 120px) !important; }

  /* Services rows (.svc): the mobile grid keeps a 32px gap + wide fixed
   * columns, starving the title column so long words ("transformation")
   * couldn't fit and expanded the grid ~87px past the viewport. Tighten the
   * columns/gap and lower the title floor so titles wrap within the row. */
  .services-list .svc { grid-template-columns: 26px 1fr 44px; gap: 10px; }
  .services-list .svc-title { font-size: clamp(21px, 6vw, 40px); }
  /* The svc hover highlight (::before) bleeds 32px past the row for a
   * full-width effect on desktop; on a phone that 32px runs past the screen
   * edge (~12px overflow). Match it to the 20px page gutter instead. */
  .services-list .svc::before { left: -20px; right: -20px; }
}

/* Topbar at narrow widths: logo + "Talk to us" pill + hamburger don't all fit
 * below ~430px, so the hamburger was pushed off-screen. Drop the redundant CTA
 * pill on small phones — the hamburger drawer already carries "Talk to us →". */
@media (max-width: 430px) {
  .topbar .nav-cta { display: none; }
}

/* =====================================================================
 * Dark-mode legibility: the tertiary/metadata colour (--fg-3 #6F6E69) is a
 * mid-grey that reads fine on the light cream background but drops below a
 * comfortable contrast on the near-black dark canvas (hero meta, eyebrows,
 * section numbers). Brighten --fg-3 for DARK mode only — the light theme
 * carries its own [data-theme="light"] --fg-3 (higher specificity), so this
 * :root override never touches light mode.
 * ===================================================================== */
/* Scope to dark only via :not([data-theme="light"]) — a plain :root has the
 * SAME specificity as styles.css's [data-theme="light"] and, loading later,
 * would wrongly override light mode too (washing out its tertiary text). The
 * :not() raises specificity AND excludes the light theme entirely. */
:root:not([data-theme="light"]) { --fg-3: #B5B4AB; }

/* LIGHT mode: the design's tertiary grey (#6F6E69) on the cream canvas sits
 * at ~4.5:1 — technically passing but visibly washed out for the small 11-13px
 * body/metadata text that uses it (capability cards, eyebrows, section
 * numbers, footer headings). Darken it to ~7:1 so it reads comfortably.
 * --fg-2 is darkened slightly too for card body copy. */
:root[data-theme="light"] { --fg-3: #55544E; --fg-2: #33333A; }

/* Mobile topbar: guarantee breathing room between the CTA and the menu
 * button, and a comfortable tap target for the hamburger. */
@media (max-width: 900px) {
  .topbar .nav-cta { margin-left: auto; margin-right: 12px; }
  .menu-btn { flex: 0 0 auto; }
}

/* Industries grid (.stack on tech-consulting): the design's 3-columns-on-mobile
 * rule was tuned for one-word tech names. Our industry chips carry longer
 * labels ("Healthcare & Pharma") + a detail line, whose min-content width can't
 * shrink to a third of a phone screen, so the 3rd column overflowed (~15px
 * clipped). Drop to 2 columns on phones and let long words wrap. */
@media (max-width: 620px) {
  /* `.wrap .stack` (0,2,0) out-specifies the page's own inline `.stack`
     (0,1,0) rule, which loads after overrides.css and would otherwise win. */
  .wrap .stack { grid-template-columns: 1fr 1fr; }
}
.wrap .chip .name, .wrap .chip .cat { overflow-wrap: break-word; }

/* Grid/flex children default to min-width:auto, which refuses to shrink below
 * their content's min-content size — on the contact page this let the enquiry
 * form spill past its column (20px left gap but ~1px right gap). Allowing the
 * items to shrink restores symmetric gutters. Harmless where content already
 * fits. */
.grid > *, .footer-grid > *, .cta-actions, .submit-row,
.ct-aside, .ct-aside > * { min-width: 0; }
form.enquiry, .field input, .field textarea, .field select { max-width: 100%; }
/* Long unbreakable tokens (the support@ email, phone) in the contact aside
 * cards forced the card wider than a phone — let them wrap. */
.ct-card h4, .ct-card h4 a { overflow-wrap: anywhere; }

/* =====================================================================
 * Card breathing room + alignment
 * ===================================================================== */
/* Capability / feature / value cards keep a 32px desktop padding that eats
 * most of a half-width phone column, leaving text pressed against the right
 * border. Tighten it on phones and let long words break. */
/* Two-class selectors (0,2,0) so these beat each page's own inline `.cap`
 * (0,1,0) rules, which load after this file. */
@media (max-width: 700px) {
  .cap-grid .cap,
  .values .value,
  .engagement .eng,
  .feature-row .feat-cell,
  .feat-grid .feat { padding: 20px; }
  .cap-grid .cap h3, .cap-grid .cap p,
  .values .value p, .feature-row .feat-cell p { overflow-wrap: break-word; }
}

/* Founder card meta rows: label and value are a space-between flex pair with
 * no gap, so a long value ("Architect · Engineer · AI-native builder") collided
 * with its label and wrapped underneath it. Give them a gap, let the value
 * wrap on its own line, and keep the label from shrinking. */
.founder-meta .row { gap: 16px; align-items: baseline; flex-wrap: wrap; }
.founder-meta .row .k { flex: 0 0 auto; }
.founder-meta .row .v { text-align: right; margin-left: auto; }
/* When the card is narrow the longest value ("Architect · Engineer · AI-native
 * builder") can't share a line with its label; wrapping it right-aligned reads
 * ragged, so stack label-over-value, both left-aligned. */
@media (max-width: 900px) {
  .founder-meta .row { flex-direction: column; gap: 4px; }
  .founder-meta .row .v { text-align: left; margin-left: 0; }
}

/* Career rows: role and org sat flush against each other. */
.career-row .role { line-height: 1.25; }
.career-row .org { margin-top: 3px; }

/* =====================================================================
 * Footer layout on small screens
 * ---------------------------------------------------------------------
 * The 2-column mobile grid put the big brand statement in a half-width
 * column beside the first link list, which read as broken alignment. Give
 * the brand block the full row, then let the four link lists sit in two
 * even columns beneath it.
 * ===================================================================== */
@media (max-width: 900px) {
  .footer-grid > div:first-child { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: 8px; text-align: left; }
}
