/* DALiApps, LLC — daliapps.dev
 *
 * One stylesheet for all three pages (index, privacy, 404). It used to be three copy-pasted
 * <style> blocks that had already drifted apart (404.html and privacy.html were each missing
 * tokens the landing page had).
 *
 * The CSP served by CloudFront is
 *   default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'
 * so: no CDN anything. The font below is self-hosted, every image is same-origin, and there is no
 * JavaScript on this site at all — web/privacy.html promises visitors exactly that in writing, so
 * every interaction here is CSS-only.
 */

/* Geist — SIL Open Font License 1.1, (c) 2023 Vercel in collaboration with basement.studio.
 * Full license text ships alongside the font at /fonts/OFL.txt, as the OFL requires.
 * One variable file covers 100-900, which is smaller than the two static weights it replaces. */
@font-face {
  font-family: 'Geist';
  src: url('/fonts/Geist-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------------------------------------------------------------- palette
 *
 * "Petrol & Brass" — see docs/brand/house-identity-rollout.md. Aggie maroon #500000 is RETIRED
 * along with the per-product coral and gold; do not restore them.
 *
 * Two layers, and the split matters:
 *   - BRAND CONSTANTS are fixed hexes. They never change with the colour scheme.
 *   - ROLE TOKENS are what every rule below actually references, and they are the only names the
 *     dark block overrides. It overrides VALUES only and introduces no new name, so a rule cannot
 *     silently reference a token that exists in one scheme and not the other.
 *
 * A deep brand colour cannot keep the same job on a dark canvas: petrol as a filled button on
 * #10171A measures 1.46:1, i.e. invisible. So --fill and --heading invert to the lifted values in
 * dark rather than staying petrol. Every ratio quoted here was computed with the WCAG 2.x
 * relative-luminance formula, checked against the black-on-white = 21.00 pin.
 */
:root {
  /* Brand constants. */
  --petrol: #0e3a40;      /* 11.57 on cream · white on it 12.37 */
  --petrol-lift: #5fb8c4; /* 7.88 on the dark canvas */
  --brass: #9a6410;       /* 4.67 on cream · 4.99 on white */
  --brass-lift: #e0aa4e;  /* 8.65 on the dark canvas */

  /* Roles — light. Canvas is a warm cream rather than a blue-grey white; that is most of the
   * site's character, and it is the reason the accent had to be a mid-tone brass. */
  --canvas: #f9f7f4;
  --canvas-2: #f1eeea;
  --surface: #ffffff;
  --ink: #1e1e24;         /* 15.51 on canvas */
  --muted: #6d6a67;       /* 5.03 on canvas · 4.65 on canvas-2 */
  --line: #e2ded7;

  --heading: var(--petrol);
  --accent: var(--brass);
  --fill: var(--petrol);
  --fill-hover: #155a64;  /* white on it 7.84 */
  --on-fill: #ffffff;
  /* A dark drop shadow does nothing on a dark canvas, so this is a role token too, not a literal. */
  --shadow: 0 12px 32px -18px rgba(30, 30, 36, 0.45);
  --mark-keyline: transparent;

  --r-card: 14px;
  --r-lg: 20px;
  --r-pill: 999px;

  --max: 1120px;
  --gutter: clamp(20px, 5vw, 40px);
  --sec: clamp(64px, 9vw, 128px);

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --canvas: #10171a;
    --canvas-2: #161f23;
    --surface: #162024;   /* 1.09 lift off the canvas — enough to read as a raised card */
    --ink: #eaf0f1;       /* 15.72 on canvas · 14.40 on surface */
    --muted: #9aa8ab;     /* 7.39 on canvas · 6.76 on surface */
    --line: #2a3b41;

    /* The inversion. */
    --heading: var(--petrol-lift);
    --accent: var(--brass-lift);
    --fill: var(--petrol-lift);
    --fill-hover: #8ed2dc; /* canvas-coloured label on it 10.70 */
    --on-fill: #10171a;    /* 7.88 on the fill */
    --shadow: 0 12px 32px -18px rgba(0, 0, 0, 0.85);
    --mark-keyline: #4a6b73;
  }
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  background: var(--canvas);
  color: var(--ink);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis-weight: none;
}

a { color: inherit; }

/* padding-INLINE, not the `padding` shorthand: .wrap sits on the same elements as <section>
 * (`<section id="apps" class="wrap">`), so a class shorthand beats the `section` rule below on
 * specificity and silently zeroes the vertical rhythm between every section. */
.wrap { max-width: var(--max); margin: 0 auto; padding-inline: var(--gutter); }
.wrap-narrow { max-width: 760px; }

/* Anchored sections must clear the sticky nav when jumped to. */
[id] { scroll-margin-top: 96px; }

.eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Every mark carries its own petrol field. That field is 11.57:1 against the cream canvas, but only
 * 1.34:1 against the dark card surface — on a dark scheme the tile disappears and the white glyph
 * appears to float, which is visible only in a render. A hairline puts the edge back; it reads
 * against both sides (2.14 vs the petrol field, 2.88 vs the surface) and is decorative, so no AA
 * floor applies. `outline` rather than `border` so nothing shifts, and it follows border-radius. */
.nav-brand img, .footer-brand img, .stage-card img, .card img.icon, .btn img, .center-page img {
  outline: 1px solid var(--mark-keyline);
  outline-offset: -1px;
}

/* ---------------------------------------------------------------- nav */

/* The gutter lives on the outer element: .nav sets its own padding for the pill's interior, which
 * would otherwise override the horizontal padding .wrap is trying to supply. */
.nav-outer { position: sticky; top: 0; z-index: 20; padding: 12px var(--gutter); }
.nav {
  max-width: var(--max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 10px 8px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  /* Opaque, not translucent: with no JS we cannot add a scrolled state, and a blurred bar over
   * cream reads as muddy. A solid pill is cleaner and costs nothing. */
  background: var(--surface);
}
.nav-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; font-weight: 600; letter-spacing: -0.02em; }
.nav-brand img { width: 26px; height: 26px; border-radius: 7px; display: block; }
.nav-links { display: flex; gap: 4px; margin-left: auto; }
.nav-links a {
  padding: 6px 12px;
  border-radius: var(--r-pill);
  text-decoration: none;
  font-size: 15px;
  color: var(--muted);
  transition: color 0.15s ease, background-color 0.15s ease;
}
.nav-links a:hover { color: var(--ink); background: var(--canvas-2); }
.nav-cta {
  padding: 9px 18px;
  border-radius: var(--r-pill);
  background: var(--fill);
  color: var(--on-fill);
  text-decoration: none;
  font-size: 15px;
  font-weight: 550;
  white-space: nowrap;
  transition: background-color 0.15s ease;
}
.nav-cta:hover { background: var(--fill-hover); }
@media (max-width: 720px) {
  .nav-links { display: none; }
  .nav { padding-left: 14px; }
  /* margin-left:auto lives on .nav-links, which is now hidden — move it to the button. */
  .nav-cta { margin-left: auto; }
}

/* ---------------------------------------------------------------- hero */

.hero { padding-block: clamp(48px, 8vw, 104px) var(--sec); }
.hero h1 {
  color: var(--heading);
  font-size: clamp(38px, 7.2vw, 88px);
  line-height: 0.98;
  letter-spacing: -0.04em;
  font-weight: 600;
  max-width: 15ch;
  margin-top: 18px;
  text-wrap: balance;
}
.hero .lead {
  margin-top: 24px;
  max-width: 56ch;
  font-size: clamp(18px, 1.6vw, 21px);
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--muted);
}
.hero .lead strong { color: var(--ink); font-weight: 550; }

.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 36px; }
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 24px;
  border-radius: var(--r-pill);
  text-decoration: none;
  font-size: 16px;
  font-weight: 550;
  letter-spacing: -0.01em;
  border: 1px solid transparent;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.btn-primary { background: var(--fill); color: var(--on-fill); }
.btn-primary:hover { background: var(--fill-hover); }
.btn-secondary { background: var(--surface); border-color: var(--line); color: var(--ink); }
.btn-secondary:hover { border-color: var(--ink); }
.btn img { width: 22px; height: 22px; border-radius: 6px; display: block; }

/* The hero "stage": the two product marks, tilted, standing in for product screenshots we do not
 * have. Purely decorative — the same two apps are linked with real text just below. */
.stage {
  margin-top: clamp(48px, 7vw, 88px);
  display: flex;
  justify-content: center;
  gap: clamp(16px, 4vw, 48px);
  perspective: 1200px;
}
.stage-card {
  flex: 0 1 260px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(18px, 2.5vw, 28px);
  text-align: center;
  transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.stage-card:first-child { transform: rotate(-3deg) translateY(6px); }
.stage-card:last-child { transform: rotate(3deg) translateY(6px); }
.stage-card img { width: clamp(56px, 8vw, 80px); height: auto; border-radius: 18px; display: block; margin: 0 auto; }
.stage-card .name { margin-top: 14px; font-weight: 600; letter-spacing: -0.02em; }
.stage-card .kind { font-size: 14px; color: var(--muted); }
@media (prefers-reduced-motion: no-preference) {
  .stage:hover .stage-card { transform: rotate(0deg) translateY(0); }
}

/* ---------------------------------------------------------------- sections */

section { padding-bottom: var(--sec); }

h2 {
  color: var(--heading);
  font-size: clamp(28px, 3.6vw, 46px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-weight: 600;
  text-wrap: balance;
}
.section-head { margin-bottom: clamp(28px, 4vw, 48px); }
.section-head h2 { margin-top: 12px; }
.section-head p { margin-top: 14px; max-width: 54ch; color: var(--muted); font-size: clamp(17px, 1.4vw, 19px); }

/* --- app cards --- */
.apps-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(16px, 2vw, 24px); }
.card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(24px, 3vw, 36px);
  text-decoration: none;
  color: inherit;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.card:hover {
  transform: translateY(-3px);
  border-color: var(--heading);
  box-shadow: var(--shadow);
}
.card img.icon { width: 56px; height: 56px; border-radius: 14px; display: block; }
.card .badge {
  display: inline-block;
  align-self: flex-start;
  margin-top: 20px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: var(--canvas-2);
  color: var(--muted);
}
.card h3 { margin-top: 14px; color: var(--heading); font-size: clamp(20px, 1.8vw, 26px); line-height: 1.15; letter-spacing: -0.025em; font-weight: 600; }
.card p { margin-top: 10px; color: var(--muted); }
.card .go { margin-top: auto; padding-top: 22px; font-weight: 550; font-size: 15px; color: var(--accent); }
.card .go::after { content: ' \2192'; }

/* --- statement / prose --- */
.statement { max-width: 24ch; }
.prose-cols { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 3vw, 56px); }
.prose-cols p { color: var(--muted); }
.prose-cols p + p { margin-top: 16px; }

/* --- panels: business facts + legal links --- */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: clamp(8px, 1vw, 12px) clamp(20px, 3vw, 32px); }
dl.facts { display: grid; grid-template-columns: 15rem 1fr; }
dl.facts dt, dl.facts dd { padding: 16px 0; border-top: 1px solid var(--line); }
dl.facts dt:first-of-type, dl.facts dt:first-of-type + dd { border-top: 0; }
dl.facts dt { color: var(--muted); font-size: 15px; }
dl.facts a { color: var(--accent); text-decoration: none; }
dl.facts a:hover { text-decoration: underline; }
address { font-style: normal; }

ul.legal-links { list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 0 32px; }
ul.legal-links li { border-top: 1px solid var(--line); }
ul.legal-links li:first-child, ul.legal-links li:nth-child(2) { border-top: 0; }
/* The site's own notice is the odd one out — give it the full width instead of a ragged half-row. */
.legal-links-wide { grid-column: 1 / -1; }
ul.legal-links a { display: block; padding: 16px 0; text-decoration: none; font-size: 16px; }
/* base44's underline-wipe on hover, done with a gradient so it animates from the left. */
ul.legal-links a span {
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  padding-bottom: 2px;
  transition: background-size 0.25s ease;
}
ul.legal-links a:hover span { background-size: 100% 2px; }

/* ---------------------------------------------------------------- footer */

footer { border-top: 1px solid var(--line); background: var(--canvas-2); }
.footer-main { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: clamp(24px, 4vw, 48px); padding: clamp(48px, 6vw, 72px) 0 clamp(32px, 4vw, 48px); }
.footer-brand { display: flex; align-items: center; gap: 10px; font-weight: 600; letter-spacing: -0.02em; }
.footer-brand img { width: 26px; height: 26px; border-radius: 7px; display: block; }
.footer-tagline { margin-top: 14px; color: var(--muted); font-size: 15px; max-width: 34ch; }
.footer-col h4 { font-size: 12px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.footer-col ul { list-style: none; margin-top: 14px; }
.footer-col li + li { margin-top: 8px; }
.footer-col a { text-decoration: none; font-size: 15px; color: var(--ink); transition: color 0.15s ease; }
/* --heading, NOT --accent. The footer sits on --canvas-2, where brass measures 4.32:1 and misses
 * AA; petrol is 10.69:1 there. This is the one place on the site where the accent cannot be used
 * as text, and it is not obvious by eye — the two are only 0.18 apart against the plain canvas. */
.footer-col a:hover { color: var(--heading); }
.footer-bottom { border-top: 1px solid var(--line); padding: 24px 0 40px; color: var(--muted); font-size: 13px; }
/* On the document pages the footer is just the copyright line, with no columns above it to divide. */
.footer-bottom-flush { border-top: 0; }
.footer-bottom p + p { margin-top: 6px; }

/* ---------------------------------------------------------------- wordmark */

.wordmark { letter-spacing: -0.02em; }
/* The accent letter is part of a logotype, which WCAG 1.4.3 exempts — the word is still legible
 * from the other five letters. It clears AA on --canvas anyway (4.67); in the footer, on
 * --canvas-2, it is 4.32 and rides the exemption. */
.wordmark .i { color: var(--accent); font-style: italic; }

/* ---------------------------------------------------------------- privacy page */

.doc { padding-block: clamp(40px, 6vw, 72px) var(--sec); }
.back { display: inline-block; text-decoration: none; color: var(--muted); font-size: 15px; margin-bottom: 28px; transition: color 0.15s ease; }
.back:hover { color: var(--ink); }
.doc h1 { color: var(--heading); font-size: clamp(34px, 5vw, 60px); line-height: 1.02; letter-spacing: -0.035em; font-weight: 600; }
.doc .meta { margin-top: 16px; color: var(--muted); }
.doc h2 { font-size: clamp(21px, 2.2vw, 27px); margin-top: clamp(40px, 5vw, 56px); }
.doc p { margin-top: 14px; color: var(--muted); max-width: 68ch; }
.doc p strong { color: var(--ink); font-weight: 550; }
.doc a { color: var(--accent); }
.doc ul { margin-top: 14px; padding-left: 1.15em; color: var(--muted); }
.doc li + li { margin-top: 8px; }
.doc .panel { margin-top: 20px; padding: clamp(20px, 3vw, 28px); }
.doc .panel p:first-child { margin-top: 0; }

/* ---------------------------------------------------------------- 404 */

.center-page {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
}
.center-page img { width: 64px; height: 64px; border-radius: 16px; margin-bottom: 28px; }
.center-page .code { color: var(--heading); font-size: clamp(56px, 12vw, 96px); line-height: 1; letter-spacing: -0.05em; font-weight: 600; }
.center-page h1 { margin-top: 10px; color: var(--heading); font-size: clamp(20px, 2.4vw, 26px); letter-spacing: -0.02em; font-weight: 600; }
.center-page p { margin-top: 12px; color: var(--muted); max-width: 42ch; }
.center-page .links { margin-top: 30px; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }

/* ---------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .prose-cols { grid-template-columns: 1fr; }
  .prose-cols div + div { margin-top: 16px; }
  .footer-main { grid-template-columns: 1fr 1fr; }
  .footer-brand-col { grid-column: 1 / -1; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }
  .apps-grid { grid-template-columns: 1fr; }
  ul.legal-links { grid-template-columns: 1fr; }
  ul.legal-links li:nth-child(2) { border-top: 1px solid var(--line); }
  dl.facts { grid-template-columns: 1fr; }
  dl.facts dt { padding: 14px 0 0; }
  dl.facts dd { padding: 0 0 14px; border-top: 0; }
  dl.facts dt:first-of-type + dd { border-top: 0; }
  .stage { flex-direction: column; align-items: center; }
  /* Stacked in one column, the fan reads as two crooked cards rather than a deliberate flourish. */
  .stage-card:first-child, .stage-card:last-child { transform: none; }
  /* The column direction turns `flex: 0 1 260px` into a 260px-tall card padded with dead space —
   * once stacked, let the height follow the content. */
  .stage-card { flex: 0 0 auto; width: 100%; max-width: 320px; }
  .footer-main { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
  .stage-card { transform: none !important; }
}
