/* =====================================================================
   TaDaA PROJECTS - base.css
   ---------------------------------------------------------------------
   The foundations of the whole site:
     1.  Reset
     2.  The type scale (big, light headlines)
     3.  Layout helpers (.container, .grid, .stack)
     4.  The hairline grid - the signature structural device
     5.  Buttons, links, form fields
     6.  Dark panels (hero, services band, footer)
     7.  Dark mode

   RULES THIS FILE FOLLOWS
     * Square corners. The one radius setting defaults to 0.
     * No drop shadows anywhere. Depth comes from 1px hairlines only.
     * Colour comes from var(--...) which is set in layout/theme.liquid
       from Theme settings. There is not a single hex value below this
       comment, so the whole site restyles from the dashboard.
     * The accent (--color-accent) is only ever used for things you can
       measure in pixels: a 5px dot, a 1px line, a tag outline.
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. RESET
   ------------------------------------------------------------------ */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Form controls and scrollbars follow the light page. The site does not
     auto-switch to a dark page - see the note in layout/theme.liquid. */
  color-scheme: light;
  scroll-padding-top: calc(var(--header-height) + 20px);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body-stack);
  font-size: var(--font-size-body);
  font-weight: var(--font-body-weight);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color var(--speed) var(--ease), color var(--speed) var(--ease);
}

.main { flex: 1 0 auto; }

img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; border-style: none; }

/* Images inside a fixed-ratio frame stretch to fill it */
.media img,
.media > svg { width: 100%; height: 100%; object-fit: var(--card-fit, cover); }


/* ---------------------------------------------------------------------
   2. THE TYPE SCALE
   Headlines are LARGE and REGULAR WEIGHT - never bold. That contrast
   between huge thin type and tiny wide uppercase labels is the whole
   typographic idea, so try to keep heading weight at 400.
   Sizes are fluid: they shrink on phones and grow on wide screens.
   ------------------------------------------------------------------ */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  margin: 0;
  font-family: var(--font-heading-stack);
  font-weight: var(--font-heading-weight);
  letter-spacing: var(--heading-letter-spacing);
  line-height: 1.05;
  text-wrap: balance;
}

/* Hero scale - the biggest thing on the site */
h1, .h1 {
  font-size: calc(clamp(44px, 8.4vw, 124px) * var(--heading-scale));
  line-height: 0.98;
  letter-spacing: -0.02em;
}
/* Section headings */
h2, .h2 {
  font-size: calc(clamp(30px, 4.2vw, 54px) * var(--heading-scale));
  line-height: 1.05;
  letter-spacing: -0.01em;
}
/* Card and row headings */
h3, .h3 {
  font-size: calc(clamp(21px, 2vw, 27px) * var(--heading-scale));
  line-height: 1.2;
  letter-spacing: 0;
}
h4, .h4 {
  font-size: calc(clamp(17px, 1.4vw, 19px) * var(--heading-scale));
  line-height: 1.3;
  letter-spacing: 0;
}
h5, .h5 { font-size: calc(15px * var(--heading-scale)); line-height: 1.4; }
h6, .h6 { font-size: calc(13px * var(--heading-scale)); line-height: 1.4; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease),
              opacity var(--speed) var(--ease);
}
a:hover { color: var(--color-accent); }

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

hr, .rule {
  border: 0;
  border-top: var(--border);
  margin: 0;
}

/* ---- The small uppercase label ----
   Used for eyebrows, nav links, buttons, tags and column headings.
   Tiny (11px), wide letter spacing, never bold. This is the quiet
   counterweight to the very large headlines, so keep it consistent. */
.eyebrow,
.text-label,
.label {
  font-family: var(--font-body-stack);
  font-size: var(--label-size);
  font-weight: 400;
  letter-spacing: var(--label-spacing);
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--color-text-muted);
}

/* The accent dot before an eyebrow. This is the accent at its most
   typical: 5 pixels across, nothing more. */
.eyebrow .dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: var(--color-accent);
  margin-inline-end: 12px;
  vertical-align: middle;
}

.text-muted { color: var(--color-text-muted); }
.text-soft { color: var(--color-text-soft); }
.text-accent { color: var(--color-accent); }
.text-balance { text-wrap: balance; }
.text-pretty { text-wrap: pretty; }

/* Lead paragraph - the description under a headline */
.text-lead {
  font-size: clamp(15px, 1.3vw, 18px);
  line-height: 1.75;
  color: var(--color-text-soft);
  max-width: 46ch;
  text-wrap: pretty;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 0;
  z-index: 999;
  padding: 14px 22px;
  background: var(--color-button-bg);
  color: var(--color-button-text);
  font-size: var(--label-size);
  letter-spacing: var(--label-spacing);
  text-transform: uppercase;
}
.skip-link:focus { top: 0; color: var(--color-button-text); }

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}


/* ---------------------------------------------------------------------
   3. LAYOUT HELPERS
   .container   the centred column; its side padding comes from settings
   .section     one step of vertical rhythm, also from settings
   ------------------------------------------------------------------ */
.container {
  width: 100%;
  max-width: calc(var(--page-width) + var(--page-padding) * 2);
  margin-inline: auto;
  padding-inline: var(--page-padding);
}
.container--narrow { max-width: calc(860px + var(--page-padding) * 2); }
.container--wide { max-width: calc(1800px + var(--page-padding) * 2); }

.section { padding-block: var(--section-spacing); }
.section--tight { padding-block: calc(var(--section-spacing) * 0.6); }
.section--flush-top { padding-block-start: 0; }
.section--flush-bottom { padding-block-end: 0; }

/* A hairline above a section. This is how sections are separated -
   never with a colour block or a heavy border. */
.section--bordered { border-top: var(--border); }

/* Stacks = vertical rhythm. --stack-space controls the gap. */
.stack { display: flex; flex-direction: column; gap: var(--stack-space, 16px); }
.stack--xs { --stack-space: 6px; }
.stack--sm { --stack-space: 10px; }
.stack--md { --stack-space: 18px; }
.stack--lg { --stack-space: 28px; }
.stack--xl { --stack-space: 44px; }

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cluster-space, 16px);
}
.cluster--between { justify-content: space-between; }

/* ---------------------------------------------------------------------
   SECTION HEADING ROW
   Big thin heading on the left, a short paragraph on the right, and a
   hairline underneath. Deliberately spacious above the rule.
   ------------------------------------------------------------------ */
.sec-head,
.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap;
  padding-bottom: 24px;
  margin-bottom: 40px;
  border-bottom: var(--border);
}
.section-head__text { max-width: 60ch; }
.section-head .text-lead,
.sec-head p { margin: 0; max-width: 44ch; font-size: 15px; color: var(--color-text-soft); }
.section-head h2 { margin-top: 22px; }
.section-head .eyebrow + h2 { margin-top: 22px; }


/* ---------------------------------------------------------------------
   4. THE HAIRLINE GRID  (the signature structural device)
   Instead of cards with gaps and shadows, blocks sit in a grid divided
   by 1px lines: gap:1px with the line colour showing through, plus a
   1px outer border. That single trick is what makes the page feel like
   ruled drawing paper rather than a typical shop.

   Use .line-grid and make each child a .line-cell.
   ------------------------------------------------------------------ */
.line-grid {
  display: grid;
  gap: var(--border-width);
  background-color: var(--color-border);
  border: var(--border);
}
.line-cell {
  background-color: var(--color-bg);
  padding: clamp(26px, 3vw, 46px);
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: background-color var(--speed) var(--ease), color var(--speed) var(--ease);
}
/* On hover a cell inverts to the dark panel - a strong, quiet move that
   needs no shadow or colour. */
.line-cell:hover {
  background-color: var(--color-ink);
  color: var(--color-ink-text);
}
.line-cell:hover .text-muted,
.line-cell:hover .text-soft,
.line-cell:hover p { color: var(--ink-text-soft); }
.line-cell:hover .label,
.line-cell:hover .eyebrow { color: var(--ink-text-faint); }

/* ---- Responsive grid ---- */
.grid {
  display: grid;
  gap: var(--grid-gap);
  grid-template-columns: repeat(var(--columns, 3), minmax(0, 1fr));
}
.grid--auto {
  grid-template-columns: repeat(auto-fill, minmax(min(var(--min-col, 260px), 100%), 1fr));
}
.grid--2 { --columns: 2; }
.grid--4 { --columns: 4; }

/* Phones: one column. Three cards across 390px is unreadable. */
@media (max-width: 599px) {
  .grid,
  .grid--2,
  .grid--4,
  .grid--auto { grid-template-columns: 1fr; }
  .section-head,
  .sec-head { margin-bottom: 36px; padding-bottom: 22px; }
}
/* Small tablets: four-across becomes two-across. */
@media (min-width: 600px) and (max-width: 989px) {
  .grid--4 { --columns: 2; }
  .line-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 819px) {
  .line-grid { grid-template-columns: 1fr; }
}

/* ---- Fixed-ratio image frame ---- */
.media {
  position: relative;
  overflow: hidden;
  background-color: var(--color-bg-alt);
  border: var(--border);
  border-radius: var(--radius);
  aspect-ratio: var(--ratio, 4 / 5);
}
.media--adapt { aspect-ratio: auto; }
.media--adapt img { height: auto; object-fit: contain; }
.media > img,
.media > svg {
  position: absolute;
  inset: 0;
  transition: transform var(--speed-slow) var(--ease), opacity var(--speed) var(--ease);
}
.media--adapt > img,
.media--adapt > svg { position: static; }
.media--zoom:hover > img { transform: scale(1.06); }

.placeholder-svg {
  width: 100%; height: 100%;
  background-color: var(--color-bg-alt);
  fill: var(--color-border);
}


/* ---------------------------------------------------------------------
   5. BUTTONS, LINKS, FORMS
   Buttons are rectangles with a 1px edge that INVERT on hover. No
   rounding, no shadow, no accent fill.
   ------------------------------------------------------------------ */
.button,
.btn,
button.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 17px 30px;
  min-height: 52px;
  border: var(--border-width) solid var(--color-button-bg);
  border-radius: var(--radius);
  background-color: var(--color-button-bg);
  color: var(--color-button-text);
  font-family: var(--font-body-stack);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: var(--label-spacing);
  text-transform: uppercase;
  line-height: 1;
  text-align: center;
  cursor: pointer;
  appearance: none;
  transition: background-color var(--speed) var(--ease), color var(--speed) var(--ease),
              border-color var(--speed) var(--ease), opacity var(--speed) var(--ease);
}
/* Hover inverts: the fill empties and the text takes the page colour. */
.button:hover,
.btn:hover {
  background-color: transparent;
  color: var(--color-button-bg);
  border-color: var(--color-button-bg);
}
.button[disabled],
.button[aria-disabled='true'] {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Outline version: starts empty, fills in on hover. */
.button--outline {
  background-color: transparent;
  color: var(--color-text);
  border-color: var(--color-border);
}
.button--outline:hover {
  background-color: var(--color-text);
  border-color: var(--color-text);
  color: var(--color-bg);
}

/* Text-only version, for "View all" and "Enquire". */
.button--text {
  padding: 0;
  min-height: 0;
  border: 0;
  background: none;
  color: var(--color-text);
  font-size: 12px;
  gap: 12px;
}
.button--text:hover { background: none; color: var(--color-accent); }

.button--small { padding: 13px 20px; min-height: 44px; font-size: 11px; }
.button--full { width: 100%; }

/* ---- Inline link with a hairline underline that warms to the accent ----
   Another place the accent is allowed to appear: a 1px line. */
.link-underline,
.link-u {
  display: inline-block;
  padding-bottom: 5px;
  border-bottom: var(--border-width) solid var(--color-border);
  transition: border-color var(--speed) var(--ease), color var(--speed) var(--ease);
}
.link-underline:hover,
.link-u:hover { border-bottom-color: var(--color-accent); color: var(--color-accent); }

/* Arrow that slides on hover. */
.link-arrow { display: inline-flex; align-items: center; gap: 12px; }
.link-arrow .icon { transition: transform var(--speed) var(--ease); }
.link-arrow:hover .icon { transform: translateX(5px); }

/* ---- Form fields ---- */
.field {
  display: block;
  width: 100%;
  padding: 17px 20px;
  border: var(--border);
  border-radius: var(--radius);
  background-color: transparent;
  color: var(--color-text);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  appearance: none;
  transition: border-color var(--speed) var(--ease);
}
.field::placeholder { color: var(--color-text-muted); }
.field:focus { border-color: var(--color-text); outline: none; }
textarea.field { min-height: 150px; resize: vertical; }

.field-label {
  display: block;
  margin-bottom: 10px;
  font-size: var(--label-size);
  font-weight: 400;
  letter-spacing: var(--label-spacing-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.form-status {
  margin-top: 14px;
  font-size: 14px;
  color: var(--color-accent);
}
.form-status--error { color: #b3261e; }


/* ---------------------------------------------------------------------
   6. DARK PANELS
   The hero, the services band, the footer and any section given
   .panel-ink sit on near-black with light text. Everything inside them
   switches to the light-on-dark variables automatically, so a section
   only needs one class to flip.
   ------------------------------------------------------------------ */
.panel-ink {
  background-color: var(--color-ink);
  color: var(--color-ink-text);
}
.panel-ink,
.panel-ink h1, .panel-ink h2, .panel-ink h3, .panel-ink h4 { color: var(--color-ink-text); }
/* Paragraph copy on a dark panel uses the panel's own muted colour, never
   --color-text-soft: that one flips with the colour scheme, and in dark
   mode it would come out almost the same colour as the near-black panel. */
.panel-ink p,
.panel-ink .text-lead,
.panel-ink .text-soft { color: var(--ink-text-soft); }
.panel-ink .text-muted,
.panel-ink .eyebrow,
.panel-ink .text-label { color: var(--ink-text-faint); }
.panel-ink a:hover { color: var(--color-ink-text); }
.panel-ink .rule,
.panel-ink hr,
.panel-ink .section-head { border-color: var(--line-on-ink); }

/* A hairline rule on a dark panel */
.rule-ink { border-top: var(--border-ink); }

/* The engineering grid: faint 88px graph paper, faded out with a radial
   mask so it reads as a technical drawing rather than a table.
   Used by the hero and the closing call-to-action. */
.blueprint {
  position: relative;
  overflow: hidden;
}
.blueprint::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line-on-ink) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-on-ink) 1px, transparent 1px);
  background-size: 88px 88px;
  opacity: 0.5;
  -webkit-mask-image: radial-gradient(ellipse at 65% 50%, #000 10%, transparent 78%);
  mask-image: radial-gradient(ellipse at 65% 50%, #000 10%, transparent 78%);
}
.blueprint--centre::before {
  -webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000, transparent 72%);
  mask-image: radial-gradient(ellipse at 50% 50%, #000, transparent 72%);
  opacity: 0.4;
}
.blueprint > * { position: relative; z-index: 2; }

/* Buttons on a dark panel: light fill, inverting on hover. */
.panel-ink .button {
  background-color: var(--color-ink-text);
  border-color: var(--color-ink-text);
  color: var(--color-ink);
}
.panel-ink .button:hover {
  background-color: transparent;
  color: var(--color-ink-text);
  border-color: var(--color-ink-text);
}
.panel-ink .button--outline {
  background-color: transparent;
  color: var(--color-ink-text);
  border-color: var(--line-on-ink);
}
.panel-ink .button--outline:hover {
  background-color: var(--color-ink-text);
  border-color: var(--color-ink-text);
  color: var(--color-ink);
}
.panel-ink .button--text { background: none; color: var(--color-ink-text); }
.panel-ink .button--text:hover { color: var(--color-accent); }

/* Logo artwork.
   The theme ships two files - black ink and white ink - and swaps between
   them by class rather than by inverting one bitmap, because inverting
   turns the anti-aliased edges into a pale halo.

   .logo-auto-invert is only used for an UPLOADED logo when no separate
   dark-mode file was supplied, so a single upload still works on the dark
   panels. It no longer reacts to the device colour scheme. */
.logo-auto-invert { transition: filter var(--speed) var(--ease); }
.panel-ink .logo-auto-invert,
.panel-ink .logo-force-light { filter: invert(1) brightness(1.06); }


/* ---------------------------------------------------------------------
   SECTION BOUNDARIES - SOLID, NO GRADIENTS
   ---------------------------------------------------------------------
   The reference page changes from a dark band to a light one as a HARD
   EDGE, and that is deliberate: the crisp change is part of the look. A
   gradient in between reads as a mistake or a rendering artefact.

   So there are exactly two treatments, and nothing else:

     dark panel <-> light section   a clean hard cut, no rule
     light section <-> light section  a single 1px hairline

   If you want a hairline between a dark panel and a light section too,
   give that section "show_top_border" in its settings.

   The old gradient bridge elements are gone. Any .bridge left in a
   template now renders as nothing at all.
   ------------------------------------------------------------------ */
.bridge { display: none; }

/* The last band inside a dark section is flat - no fade to a lighter tone. */
.panel-ink--to-light { background-image: none; }

/* The footer is solid panel colour from its first pixel. */
.footer { background-image: none; }

/* ---------------------------------------------------------------------
   7. UTILITIES
   ------------------------------------------------------------------ */
.hidden, [hidden] { display: none !important; }
.relative { position: relative; }
.full-bleed { width: 100%; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.no-scroll { overflow: hidden; }

.bg-warm { background-color: var(--color-bg-alt); }
.bg-ink { background-color: var(--color-ink); color: var(--color-ink-text); }

/* Scroll reveal. Sections fade up gently as they come into view. */
.reveal,
.rv { opacity: 0; transform: translateY(26px); }
.reveal.is-visible,
.rv.in {
  opacity: 1;
  transform: none;
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .reveal, .rv { opacity: 1; transform: none; }
}
