/* Amoleo Light and Amoleo Dark's shared five (bg/panel/text/muted/border),
   every --brand-* accent, --brand-amoleo, radii and shadows, and the
   generic reset/typography/buttons/focus-ring/.wrap/.skip-link/
   .visually-hidden/reduced-motion primitives all now come from the three
   files linked in <head> before this one — family-css/{amoleo-light,
   amoleo-dark,base}.css, synced from Amoleo-Family and never hand-edited
   here. See Amoleo-Family/docs/family-css-system.md. This file carries
   only what's still genuinely this site's own: --accent/--on-accent
   (Website has no sub-brand, so --accent is the AMOLEO wordmark's own
   colour rather than a product accent), --text-strong (per-site by design,
   family-theme.md §1), --panel-2 (a second surface tone, not the shared
   --border concept even though the two happen to share a value today),
   --wrap/--step (this page's own layout rhythm — no evidence another repo
   shares the concept), and this one page's actual content. */

:root {
  /* Unreferenced today, and not the wordmark's colour — that is --brand-amoleo
     in family-css/amoleo-light.css / amoleo-dark.css. */
  --brand: #1c1c2e;

  --wrap: 1080px;
  --step: clamp(56px, 9vw, 104px);
}

/* Dark is the default so a browser that reports no preference gets the theme the
   apps default to, rather than a flash of the other one — matching
   family-css/amoleo-dark.css's own unconditioned :root. */
:root, [data-theme="dark"] {
  color-scheme: dark;
  --panel-2: #2b2b33;
  --text-strong: #ffffff;
  --accent: #9a9ae0;
  --on-accent: #101013;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --panel-2: #e0e0e6;
    --text-strong: #1c1c2e;
    --accent: #1c1c2e;
    --on-accent: #ffffff;
  }
}

/* Kept as an explicit selector as well as a media query so that adding a theme
   toggle later is a matter of setting data-theme, with no CSS restructuring. */
[data-theme="light"] {
  color-scheme: light;
  --panel-2: #e0e0e6;
  --text-strong: #1c1c2e;
  --accent: #1c1c2e;
  --on-accent: #ffffff;
}

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

   The shared three-class rule (.brand-wordmark/.brand-dot/.brand-suffix —
   weight, tracking, colour, the 0.79em suffix/dot ratio) and the base
   .inline-mark sizing (display/vertical-align/font-size) now live in
   family-css/base.css, linked in <head> before this file. What's left here
   is what's genuinely this site's own: .brand-name and the compound
   "Amoleo · Rissbrook" inline-link behaviour below — Pets ships the same
   base .inline-mark rule but has no compound-link construct of its own to
   need either of these. */

/* Only needed once the name sits inside an <a> of its own (the inline
   compound mention below, where "Amoleo" and the suffix share one link) —
   the base `a { color: var(--accent) }` rule sits between the anchor and
   .brand-wordmark's own colour, so an unstyled .brand-name inside a link
   inherits the generic link colour instead of the family colour. Explicit,
   same as .brand-dot/.brand-suffix already are, rather than relying on
   inheritance reaching past an anchor that happens not to exist yet
   anywhere else. */
.brand-wordmark .brand-name { color: var(--brand-amoleo); }

/* ---- inline (running text) ---- */
.inline-mark.rissbrook { --wordmark-accent: var(--brand-rissbrook); }
/* Cross-link behaviour for a compound mention (e.g. "Amoleo · Rissbrook"
   linking out to that product's own site). Same underlying rule as the
   footer lockup's cross-link (family-wordmark.md §6): a decoration goes
   directly on the specific text span, never on the <a> itself, so nothing
   leaks onto the dot and each part's line renders in that part's own
   colour rather than one shared link colour. This instance goes one step
   further than the footer's — "Amoleo" sits inside the same <a> as the
   dot and suffix (the whole compound mark is one link to Rissbrook here,
   not just the product name on its own), so it gets the identical
   direct-span treatment as .brand-suffix: its own hover rule, its own
   colour (inherited from .brand-wordmark's base --brand-amoleo, unchanged
   by the .rissbrook accent override that only touches dot/suffix). */
.inline-mark a { text-decoration: none; }
.inline-mark a:hover .brand-name { text-decoration: underline; }
.inline-mark a:hover .brand-suffix { text-decoration: underline; }

/* ---- header ----

   The Pre-Auth header (.family-header/.family-header-bar, burger, drawer)
   is fully shared now — family-css/base.css, header.css component. Nothing
   of it is site-specific enough to keep here. See
   Amoleo-Family/docs/family-header.md. */

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

.hero { padding: calc(var(--step) * 1.1) 0 var(--step); }
.hero h1 {
  font-size: clamp(34px, 6.2vw, 60px);
  letter-spacing: -0.02em;
  max-width: 16ch;
  margin-bottom: 24px;
}
.hero-sub {
  font-size: clamp(18px, 2.2vw, 22px);
  color: var(--muted);
  max-width: 54ch;
  margin: 0;
}

/* ---- work ---- */

.section-heading {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: var(--step);
}

.work { padding-bottom: var(--step); }

.product {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(32px, 6vw, 72px);
  align-items: center;
  margin-bottom: calc(var(--step) * 1.15);
}

/* Alternating sides give the page a rhythm without needing a second layout.
   The order swap is visual only — the DOM order stays text-then-image, which
   is the order it should be read in. */
.product:nth-of-type(even) .product-text { order: 2; }

.product-mark { font-size: 26px; margin-bottom: 14px; }
/* Explicit, identical pixel values for both — not the base rule's 0.79em,
   which computes 26 × 0.79 = 20.54px separately for each and can round by
   a sub-pixel differently between them. Same fix as .family-mark's own
   explicit 19px for both dot and suffix. */
.product-mark .brand-suffix { font-size: 21px; }
.product-mark .brand-dot { font-size: 21px; }
.product-lede {
  font-size: clamp(19px, 2.1vw, 23px);
  color: var(--text-strong);
  font-weight: 600;
  line-height: 1.35;
  margin-bottom: 16px;
}
.product-text p:not(.product-lede):not(.product-link) { color: var(--text); }

.product-link { margin: 20px 0 0; font-weight: 600; }
.product-link a { text-decoration: none; display: flex; align-items: center;}
/* Three independent hover treatments, decorated only where each one
   should show — never on the ancestor <a> with something excluded from
   it. Excluding a descendant looked right and wasn't, twice now (the
   footer's dot, then here): even with the exclusion in place, some
   browsers still paint a sliver of the ancestor's line under the
   excluded element's margin, peeking out from behind a more specific
   override. The only fully reliable fix is to never decorate the
   ancestor at all — "Visit" and the product name each get their own
   underline, set directly on themselves; the dot and the arrow are never
   mentioned in a decoration rule, so there is nothing to leak. See
   family-wordmark.md §6, §8. */
.product-link a:hover .link-visit { text-decoration: underline; }
.product-link a:hover .link-name { text-decoration: underline; }
/* .link-text: the same "decorate the specific span, not the <a>" rule for
   a .product-link that has nothing to do with the wordmark at all (Visit
   LinkedIn) — a distinct class from .link-visit on purpose, not reused,
   because the two mean different things even though the CSS they need is
   identical. Losing this on the LinkedIn link was the direct cost of the
   fix above: removing the old ancestor-level `.product-link a:hover
   { text-decoration: underline }` fixed the wordmark links and silently
   broke the one plain-text link that had no span to catch the same rule.
   Every .product-link's visible text now needs a span, wordmark-related
   or not. */
.product-link a:hover .link-text { text-decoration: underline; }

/* LinkedIn's own mark, not the family's — "Linked" in their blue, "In" as
   their badge (blue fill, pale text), matching the real logo rather than
   inheriting whatever colour this link would otherwise get. .li-name
   underlines on hover like any other coloured text link (same rule as
   .link-text, .link-visit, .link-name above); .li-badge doesn't — a
   filled badge doesn't gain anything from an underline cutting through
   its own background. */
.li-name { color: #0f69c3; }
.li-badge {
  background: #0f69c3;
  color: #e7f0f9;
  padding: 1px 4px;
  border-radius: 3px;
  font-weight: 700;
}
.product-link a:hover .li-name { text-decoration: underline; }

/* A product is never named bare — "Visit · Pets", never "Visit Pets", so the
   name always arrives carrying the separator that ties it to the family.
   Borrows the wordmark's uppercase and letterspacing but not its sizing: this
   sits inside a sentence, at the size of the words either side of it.

   Deliberately plain inline, not flex. The wordmark proper is display:flex, and
   nesting that inside an inline-flex link in a narrow column broke "Visit",
   the name and the arrow onto three lines. Ordinary text flow does not. */
/* 700 on the name — the wordmark's own suffix weight (family-wordmark.md
   §3: "always", not size- or context-dependent), used wherever the
   product name appears, including here. The separator keeps its own 400.
   "Visit" stays at .link-mark's 600 — it isn't part of the mark.

   0.9em, not the wordmark's 0.6em. There the suffix is 0.6 of a large family
   name it hangs off; here there is no family name and the reference is the
   sentence, where 0.6em would be about 10px. The reason to go below 1em at all
   is optical rather than proportional: uppercase set at the size of the words
   around it reads as larger, because every letter reaches cap height while the
   lowercase beside it mostly sits at x-height. 0.9 brings the caps back down to
   about the height of the ascenders either side. */
.link-mark {
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-weight: 600;
  font-size: 0.8em;
  white-space: nowrap;
  color: var(--wordmark-accent, var(--accent));
}
.link-mark .link-name { font-weight: 700; }
.link-mark .link-dot {
  font-weight: 400;
  letter-spacing: 0;
  margin-right: 5px;
  margin-left: 0.4em;
}
.li-mark{
  margin-left: 0.3em;
}

/* Each product's accent drives its own wordmark, so a colour means one product
   wherever it appears.

   Pets is the exception, and not by choice. The wordmark's suffix is 0.6em, so
   in a 26px heading the product name renders at 15.6px and in a link at 16px —
   both small text, both needing 4.5:1. True terracotta #c45032 manages 4.33:1
   on light and 4.11:1 on dark.

   The footer lockup deliberately keeps #c45032, because a lockup whose colours
   differ per site defeats its purpose. That leaves the footer's 7.8px suffix
   below AA — a known family-wide issue, recorded in the family footer spec. */
.product.pets { --wordmark-accent: var(--brand-pets); }
.product.connections { --wordmark-accent: var(--brand-connections); }
.product.rissbrook { --wordmark-accent: var(--brand-rissbrook); }
.product.accounts { --wordmark-accent: var(--brand-accounts); }

/* ---- screenshots ----

   A phone shot overlapping the corner of a desktop one: honest about these being
   mobile-first apps, and it fills the column better than either alone. The
   padding on the container is what the phone overhangs into — without it the
   overhang is clipped by the grid cell. */

.product-shot {
  position: relative;
  padding: 0 6% 6% 0;
}
.shot-desktop {
  display: block;
  width: 100%;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  background: var(--panel);
}
.shot-phone {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 21%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  background: var(--panel);
}

/* ---- screenshot modal ----

   One <dialog>, reused for every shot and reshaped per click rather than four
   separate modals. is-landscape/is-portrait set the dialog's own max-width;
   the image inside is capped by both max-width and max-height and left to
   find its own size within that box, so a 1280x800 desktop shot and a
   390x844 phone shot each land in a frame proportioned for them rather than
   a single shape stretched or letterboxed to fit both. */

.shot-desktop, .shot-phone { cursor: zoom-in; }

.shot-modal {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  box-shadow: var(--shadow-lg);
  padding: 16px;
  max-height: 92vh;
  max-width: 94vw;
}
.shot-modal::backdrop { background: rgba(0, 0, 0, 0.7); }
.shot-modal.is-landscape { width: min(94vw, 1400px); }
.shot-modal.is-portrait { width: min(90vw, 440px); }
.shot-modal-img {
  display: block;
  max-width: 100%;
  max-height: calc(92vh - 32px);
  width: auto;
  height: auto;
  margin: 0 auto;
  border-radius: var(--radius-md);
}
.shot-modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-strong);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.shot-modal-close:hover { background: var(--border); }

/* The dialog's own backdrop dims the page but does not stop the page behind
   it scrolling under mouse-wheel input in every browser, so the class below
   is the belt to the dialog's braces. */
body.shot-modal-open { overflow: hidden; }

/* ---- Luke ---- */

.person {
  border-top: 1px solid var(--border);
  padding: var(--step) 0;
}
.person-inner {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.person-photo {
  width: 220px;
  height: 220px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  object-fit: cover;
  box-shadow: var(--shadow);
}
.person-text h2 {
  font-size: clamp(26px, 3.4vw, 34px);
  margin-bottom: 18px;
}

/* ---- long-form pages (privacy) ---- */

.prose { padding: calc(var(--step) * 0.7) 0 var(--step); }
.prose .wrap { max-width: 760px; }
.prose h1 { font-size: clamp(30px, 5vw, 42px); letter-spacing: -0.015em; margin-bottom: 20px; }
.prose h2 { font-size: 21px; margin: 40px 0 12px; }
.prose ul { margin: 0 0 1em; padding-left: 22px; }
.prose li { margin-bottom: 10px; }
.prose code {
  font-size: 0.9em;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.prose-meta { color: var(--muted); font-size: 15px; }

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

.site-footer {
  border-top: 1px solid var(--border);
  padding: 40px 0 56px;
  text-align: center;
}

/* The family lockup itself (.family-mark, its accent variables, its
   link/hover rules, and the mobile stacked-row block further down) now
   lives in family-css/base.css — see the "brand wordmark" comment above
   for why. */

.footer-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  margin: 24px 0 0;
  font-size: 14px;
  color: var(--muted);
}
.footer-meta a { color: var(--muted); }

.linkish {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.linkish:hover { color: var(--text-strong); }

/* .btn/.btn-hero/.btn-quiet and .consent/.consent-inner/etc. are both fully
   shared now — family-css/base.css, primitives.css and cookie-consent.css
   components. Nothing of either is site-specific enough to keep here. */

/* ---- narrow ---- */

@media (max-width: 860px) {
  .product,
  .person-inner {
    grid-template-columns: minmax(0, 1fr);
  }
  /* The alternating swap only makes sense in two columns. In one it would put
     images above their own headings. */
  .product:nth-of-type(even) .product-text { order: 0; }
  .person-photo { width: 160px; height: 160px; }
}

@media (max-width: 560px) {
  /* This site's own choice — the shared primitives.css base is 17px.
     The .family-mark stacked-row block and .consent-actions .btn's
     full-width rule (both family-css/base.css) apply at this same 560px
     breakpoint independently — nothing to restate here for either. */
  body { font-size: 16px; }
}
