/* ==========================================================================
   Epic Web Works, design system
   Palette derived from the real brand mark: deep navy ink with one bright
   cyan accent, the same relationship the logo uses (navy wordmark, cyan
   "WEB WORK" and the parallelogram dot on the i). Cyan stays a deliberately
   scarce accent, not a running colour, mirroring how sparingly the logo
   itself uses it. Signature device is a soft recurring arc built from that
   same navy-plus-cyan relationship, used as a brand mark and as a quiet
   background accent, never as decoration for its own sake.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Surface. Clean white with a cool light gray-blue for alternating
     sections, matching the logo's white-background variant rather than the
     warm cream this replaces. */
  --paper: #ffffff;
  --sand: #f2f5f7;
  --sand-2: #e4eaed;

  /* Ink. The same deep navy as the logo wordmark, not pure black. */
  --ink: #16212b;
  --ink-soft: #3d4750;
  --ink-mute: #68717a;
  --ink-faint: #9aa2a8;

  /* Accent. The logo's cyan. --cyan is a deepened, text-safe shade for links
     and icons on white (raw logo cyan fails contrast there); --cyan-bright is
     the true vivid logo cyan, reserved for dark sections, dots, and the arc
     motif where its full brightness reads correctly. */
  --cyan: #0c7c93;
  --cyan-deep: #095f70;
  --cyan-bright: #22d3ee;
  --cyan-tint: #e3f7fa;

  --line: #dde3e6;
  --line-strong: #c3cbcf;
  --line-dark: rgba(255, 255, 255, 0.14);

  --void: #0f1922;
  --void-2: #16232e;
  --void-3: #121c25;

  /* Type. Warm, confident, humanist sans throughout; no monospace anywhere
     in the public site, that register belongs to developer tools, not to an
     agency a business owner is trusting with real budget. */
  --font-display: "General Sans", "Inter Tight", "Inter", -apple-system,
    BlinkMacSystemFont, "Segoe UI Variable Display", "Segoe UI", Arial, sans-serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;

  --display-xl: clamp(2.75rem, 1.6rem + 6vw, 5.5rem);
  --display-lg: clamp(2.25rem, 1.5rem + 3.4vw, 3.75rem);
  --display-md: clamp(1.75rem, 1.4rem + 1.8vw, 2.5rem);
  --display-sm: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);

  --text-xs: 0.8125rem;
  --text-sm: 0.9375rem;
  --text-base: 1.0625rem;
  --text-lg: 1.1875rem;
  --text-xl: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);

  --label-xs: 0.75rem;
  --label-sm: 0.8125rem;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 2.5rem;
  --space-8: 3rem;
  --space-10: 4rem;
  --space-12: 5rem;
  --space-16: 7rem;

  --section-y: clamp(4rem, 2.5rem + 5.5vw, 7.5rem);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --fast: 180ms;
  --base: 380ms;
  --slow: 720ms;

  --gutter: clamp(1.25rem, 0.5rem + 3vw, 3.5rem);

  /* Radii. Generous and consistently rounded, an intentional contrast with
     the sharp-cornered developer-tool look this replaces. */
  --r-sm: 0.75rem;
  --r-md: 1.25rem;
  --r-lg: 1.75rem;
  --r-pill: 999px;

  --shadow-soft: 0 2px 10px rgba(22, 33, 43, 0.05);
  --shadow-lift: 0 20px 44px rgba(22, 33, 43, 0.10);

  /* Surface ramp. Separate from --paper/--sand/--ink*/--line* above, which
     are also used as FIXED light-on-dark values in a few permanently-dark
     spots (the void sidebar's brand mark, the printable invoice sheet, the
     sign-in card): those tokens must keep meaning "white"/"navy" regardless
     of theme, so re-theming them directly would break those spots the
     moment a dark theme is added. This ramp exists so components that
     genuinely should re-theme (panels, inputs, tables) reference these
     instead. Light values below just alias the existing tokens; the dark
     values are set once under [data-theme="dark"] a few lines down. */
  --bg: var(--sand);
  --surface: var(--paper);
  --surface-2: var(--sand);
  --text: var(--ink);
  --text-soft: var(--ink-soft);
  --text-mute: var(--ink-mute);
  --text-faint: var(--ink-faint);
  --border: var(--line);
  --border-strong: var(--line-strong);
}

/* --------------------------------------------------------------------------
   1b. Dark theme
   Opt-in via [data-theme="dark"] on <html> (see admin.js's theme toggle,
   which sets it from a localStorage preference). Only the surface ramp
   above is re-themed; every other token, including --paper/--ink/--sand/
   --line, keeps its original meaning. Today this only ever activates on
   admin pages, since only the admin panel has a toggle to set it, but the
   same block is meant to carry over once the public site gets a toggle
   too, so it lives here beside the tokens it overrides rather than in
   admin.css. */
:root[data-theme="dark"] {
  --bg: var(--void);
  --surface: var(--void-2);
  --surface-2: var(--void-3);
  --text: #e8edf1;
  --text-soft: #b7c1c9;
  --text-mute: #9aa7b0;
  --text-faint: #626d78;
  --border: var(--line-dark);
  --border-strong: rgba(255, 255, 255, 0.24);
}

/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 5.5rem; }

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--ink-soft);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, textarea, select { font: inherit; color: inherit; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }

:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: var(--r-sm); }
::selection { background: var(--cyan-tint); color: var(--cyan-deep); }

.skip-link {
  position: absolute; left: -9999px; z-index: 999;
  padding: var(--space-3) var(--space-5);
  background: var(--ink); color: var(--paper);
  border-radius: 0 0 var(--r-sm) 0;
  font-weight: 600;
}

.skip-link:focus { left: 0; top: 0; }

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */

.display {
  font-family: var(--font-display);
  font-weight: 630;
  color: var(--ink);
  line-height: 1.05;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.display--xl { font-size: var(--display-xl); letter-spacing: -0.026em; line-height: 1.03; }
.display--lg { font-size: var(--display-lg); }
.display--md { font-size: var(--display-md); line-height: 1.12; }
.display--sm { font-size: var(--display-sm); line-height: 1.2; }

.display em {
  font-style: normal;
  color: var(--cyan);
  position: relative;
  white-space: nowrap;
}

/* Soft arc drawn under emphasised words instead of a gradient or underline,
   the typographic echo of the brand mark. */
.display em::after {
  content: "";
  position: absolute;
  left: -2%;
  right: -2%;
  bottom: -0.06em;
  height: 0.42em;
  background: var(--cyan-tint);
  border-radius: 0 var(--r-lg) 0 var(--r-lg);
  z-index: -1;
}

.lede {
  font-size: var(--text-xl);
  line-height: 1.55;
  color: var(--ink-mute);
  max-width: 42ch;
  text-wrap: pretty;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--label-sm);
  font-weight: 650;
  letter-spacing: 0.02em;
  color: var(--cyan);
}

.eyebrow::before {
  content: "";
  width: 0.5rem; height: 0.5rem;
  border-radius: 50%;
  background: var(--cyan);
}

.section--void .eyebrow { color: #22d3ee; }
.section--void .eyebrow::before { background: #22d3ee; }

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */

.wrap { width: 100%; max-width: 1360px; margin-inline: auto; padding-inline: var(--gutter); }

.section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: clamp(2.5rem, 2rem + 2.5vw, 4rem); }
.section--sand { background: var(--sand); }

.section--void {
  background: var(--void);
  color: #9aa7b0;
}

.section--void .display,
.section--void .display--md { color: var(--paper); }
.section--void .lede { color: #8993a0; }

.section-head {
  max-width: 42rem;
  margin-bottom: clamp(2.5rem, 2rem + 3vw, 4rem);
}

.section-head--split {
  max-width: none;
  display: grid;
  gap: var(--space-6);
  align-items: end;
}

@media (min-width: 860px) {
  .section-head--split { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
}

.stack-2 > * + * { margin-top: var(--space-2); }
.stack-3 > * + * { margin-top: var(--space-3); }
.stack-4 > * + * { margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   5. The arc motif
   The signature device: a soft quarter-circle used as a logo mark, a section
   accent, and a card corner treatment, so it reads as one consistent brand
   idea rather than three unrelated decorations.
   -------------------------------------------------------------------------- */

/* Navy body with a cyan cutout dot: the same colour hierarchy as the real
   wordmark, where "EPIC" is navy and the only cyan is the small accent on
   the i. The brand mark should carry that relationship, not invert it. */
.arc-mark {
  --arc-size: 2.25rem;
  position: relative;
  width: var(--arc-size);
  height: var(--arc-size);
  border-radius: var(--r-md) var(--r-md) var(--r-md) 0.3rem;
  background: var(--ink);
  flex-shrink: 0;
}

.arc-mark::before {
  content: "";
  position: absolute;
  right: 18%;
  bottom: 18%;
  width: 42%;
  height: 42%;
  border-radius: 999px 0 999px 999px;
  background: var(--cyan-bright);
}

/* Uploaded logo, sized to match the arc-mark it replaces so swapping one
   for the other never shifts the surrounding layout. max-width guards
   against an unusually wide upload crowding out the nav links or the
   "Start a project" button next to it. */
.wordmark__logo { height: 2.75rem; width: auto; max-width: 13rem; flex-shrink: 0; object-fit: contain; }

/* Large decorative arc used as a quiet background accent behind hero and
   closing sections. Purely atmospheric, never interactive, always aria-hidden. */
.arc-field {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  border-radius: 999px 999px 999px 12%;
  background: var(--cyan-tint);
}

.section--void .arc-field { background: rgba(34, 211, 238, 0.07); }

/* --------------------------------------------------------------------------
   6. Cards
   Rounded, warm, generously padded. This is the primary surface, replacing
   both the earlier gradient card and the hairline index row.
   -------------------------------------------------------------------------- */

.card {
  position: relative;
  padding: var(--space-6);
  border-radius: var(--r-lg);
  background: var(--paper);
  border: 1px solid var(--line);
  transition: transform var(--base) var(--ease), box-shadow var(--base) var(--ease), border-color var(--base) var(--ease);
}

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

/* Only the card variants that are actual links get a press state; hover
   never fires on touch, so an <a> card needs its own tap feedback rather
   than relying on the hover lift above. Plain <article> feature cards are
   not clickable, so they're deliberately excluded here. */
a.card--lift:active {
  transform: translateY(-1px) scale(0.98);
  transition-duration: var(--fast);
}

.card--on-sand { background: var(--paper); }
.card--flat { border: 0; background: transparent; padding: 0; }

.card--dark {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.1);
}

.card--dark:hover { background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.16); }

.card__mark { margin-bottom: var(--space-5); }

/* Shared icon tile: the small rounded-square accent used wherever a feature,
   service, or brief item needs a mark. One definition, several call sites
   (hero brief panel, service cards, value cards, industry cells). */
.icon-tile {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.75rem 0.75rem 0.75rem 0.25rem;
  background: var(--cyan-tint);
  color: var(--cyan);
}

.icon-tile svg { width: 1.0625rem; height: 1.0625rem; }

.icon-tile--sm { width: 1.75rem; height: 1.75rem; border-radius: 0.625rem 0.625rem 0.625rem 0.2rem; }
.icon-tile--sm svg { width: 0.9375rem; height: 0.9375rem; }

.section--void .icon-tile { background: rgba(34, 211, 238, 0.14); color: #22d3ee; }

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

.section--void .card__title { color: var(--paper); }

.card__text { font-size: var(--text-sm); line-height: 1.7; color: var(--text-mute); }
.section--void .card__text { color: #8993a0; }

/* --------------------------------------------------------------------------
   7. Buttons and links
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.875rem 1.625rem;
  border-radius: var(--r-pill);
  font-size: var(--text-sm);
  font-weight: 640;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--fast) var(--ease), background-color var(--base) var(--ease),
              box-shadow var(--base) var(--ease), color var(--base) var(--ease), border-color var(--base) var(--ease);
}

.btn:hover { transform: translateY(-2px); }

/* Feedback on press, not just on release/hover: hover never fires on touch,
   so without this a tap has zero visible response until the page navigates. */
.btn:active { transform: scale(0.97); transition-duration: var(--fast); }

.btn--primary { background: var(--cyan); color: var(--paper); box-shadow: var(--shadow-soft); }
.btn--primary:hover { background: var(--cyan-deep); box-shadow: var(--shadow-lift); }

.btn--secondary { background: transparent; color: var(--text); border-color: var(--border-strong); }
.btn--secondary:hover { border-color: var(--cyan); color: var(--cyan); }

.btn--on-void { background: var(--paper); color: var(--cyan-deep); }
.btn--on-void:hover { background: #fff; }

.btn--ghost-void { background: transparent; color: var(--paper); border-color: rgba(255, 255, 255, 0.28); }
.btn--ghost-void:hover { border-color: var(--paper); }

.btn__icon { transition: transform var(--base) var(--ease); }
.btn:hover .btn__icon { transform: translateX(3px); }

/* Neither the icon-carrying span nor the raw svg some buttons use directly
   (the drawer CTA) has ever had explicit dimensions, so the icon depends on
   flex-basis:auto to size an unsized SVG, which resolves to 0px in most flex
   contexts (an invisible icon) but can balloon to the browser's replaced-
   element default in others (the drawer). Sizing it explicitly, matching
   .link svg elsewhere, removes the ambiguity everywhere at once. */
.btn svg, .btn__icon svg { width: 1rem; height: 1rem; flex-shrink: 0; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }

.link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 640;
  color: var(--cyan);
  padding-bottom: 0.2rem;
  border-bottom: 1px solid transparent;
  transition: border-color var(--base) var(--ease);
}

.link:hover { border-color: currentColor; }
.link svg { width: 1rem; height: 1rem; transition: transform var(--base) var(--ease); }
.link:hover svg { transform: translateX(3px); }

.section--void .link { color: #22d3ee; }

/* --------------------------------------------------------------------------
   8. Tags and pills
   -------------------------------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  padding: 0.3125rem 0.8125rem;
  border-radius: var(--r-pill);
  background: var(--sand);
  color: var(--ink-soft);
  font-size: var(--label-xs);
  font-weight: 620;
}

.pill--cyan { background: var(--cyan-tint); color: var(--cyan-deep); }

/* --------------------------------------------------------------------------
   9. Motion
   Gentle rise-and-fade reveals plus a drawing arc accent. No terminal-style
   line wipes; the tone here is calm, not kinetic.
   -------------------------------------------------------------------------- */

.js:not(.reveal-off) [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--slow) var(--ease-soft), transform var(--slow) var(--ease-soft);
  transition-delay: var(--reveal-delay, 0ms);
}

.js:not(.reveal-off) [data-reveal].is-revealed { opacity: 1; transform: none; }

.js:not(.reveal-off) [data-reveal="scale"] { transform: translateY(16px) scale(0.97); }

/* Arc field grows in from a point, echoing the brand mark rather than a
   generic fade. */
.js:not(.reveal-off) [data-reveal-arc] {
  transform: scale(0.85);
  opacity: 0;
  transition: transform 1100ms var(--ease-soft), opacity 900ms var(--ease-soft);
}

.js:not(.reveal-off) [data-reveal-arc].is-revealed { transform: scale(1); opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .js:not(.reveal-off) [data-reveal],
  .js:not(.reveal-off) [data-reveal-arc] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* --------------------------------------------------------------------------
   10. Utilities
   -------------------------------------------------------------------------- */

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