/* ===== MAKAPPEN.COM - shared stylesheet =====
   One copy for every page. Extracted from the single-page build on
   2026-07-29 when the site became multi-page; eleven pages each carrying
   their own 220 lines of CSS was the drift risk.

   Identity is locked (palette, type, wordmark) and composition is free
   per surface - the brand-tokens.md principle. Anything added here must
   clear PRODUCT.md's anti-references: no eyebrow pills above headings,
   no gradient text, no multi-coloured headline words, no uniform icon-card
   grids, no side-stripe callouts. */

:root{
  --white:#FFFFFF; --ink:#1A1612; --ink-soft:#4C4842; --line:#E3E0D8;
  --moss:#2F5236; --moss-deep:#24402A; --moss-wash:#EDF1E8; --moss-wash-line:#DCE3D6;
  --vivid:#37954B; --vivid-wash:#E3F1E6; --vivid-hl:rgba(55,149,75,.24);
  --coral:#F4925A;
  --ease-expo:cubic-bezier(0.16,1,0.3,1);
}
*{box-sizing:border-box;}
html,body{margin:0;background:var(--white);color:var(--ink);
  font-family:'Manrope',sans-serif;-webkit-font-smoothing:antialiased;}
html{scroll-behavior:smooth;}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto;} }
/* the sticky header would otherwise cover the top of any in-page anchor target */
:target, [id]{scroll-margin-top:104px;}
.wrap{max-width:1140px;margin:0 auto;padding:0 clamp(22px,4vw,48px);}
a{color:inherit;}
img{max-width:100%;}

/* skip link: keyboard users shouldn't tab the whole nav on every page */
.skip{position:absolute;left:-9999px;top:0;background:var(--moss);color:#fff;
  padding:12px 20px;border-radius:0 0 8px 0;font-weight:800;font-size:14px;z-index:50;}
.skip:focus{left:0;}
:focus-visible{outline:3px solid var(--vivid);outline-offset:3px;border-radius:4px;}

/* wordmark: current construction, refined */
.wm{display:inline-flex;flex-direction:column;gap:0.16em;width:max-content;
  font-weight:800;font-size:21px;letter-spacing:-0.035em;line-height:1;text-decoration:none;}
.wm .mk{color:var(--moss);} .wm .ap{color:var(--ink);}
.wm .rule{position:relative;height:0.07em;width:100%;background:var(--ink);border-radius:0.04em;}
.wm .dot{position:absolute;right:0;top:50%;width:0.26em;height:0.26em;border-radius:50%;
  background:var(--coral);transform:translate(30%,-50%);}
footer .wm .ap{color:#fff;} footer .wm .rule{background:#fff;}
footer .wm .mk{color:#96A692;}

/* sticky header. The hairline is added by JS once the page has scrolled, so
   the top of the page stays clean. No backdrop blur: glassmorphism is banned
   in PRODUCT.md, and a solid white bar is steadier over the moss bands. */
header.site{position:sticky;top:0;z-index:30;background:var(--white);
  box-shadow:0 1px 0 rgba(227,224,216,0); transition:box-shadow .3s var(--ease-expo);}
header.site.is-stuck{box-shadow:0 1px 0 var(--line), 0 8px 24px -22px rgba(26,22,18,.5);}
@media (prefers-reduced-motion: reduce){
  header.site{transition:none;}
}

nav{display:flex;align-items:center;justify-content:space-between;padding:26px 0;gap:20px;}
.navlinks{display:flex;gap:26px;align-items:center;font-size:15px;font-weight:700;}
.navlinks a{text-decoration:none;color:var(--ink-soft);}
.navlinks a:hover{color:var(--ink);}
.navlinks a.here{color:var(--ink);box-shadow:inset 0 -2px 0 var(--vivid);}
.navlinks a.btn-moss{color:#fff;}
.navlinks a.btn-moss.here{box-shadow:none;}

/* mobile menu: <details>, so it works with no JavaScript at all.
   The old build simply hid the nav under 760px, which is the width
   an App Store reviewer is most likely to be looking at. */
.menu{display:none;position:relative;}
.menu > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:9px;
  font-size:14.5px;font-weight:800;color:var(--ink);border:2px solid var(--line);
  border-radius:8px;padding:11px 16px;user-select:none;}
.menu > summary::-webkit-details-marker{display:none;}
.menu > summary .bars{display:flex;flex-direction:column;gap:3.5px;}
.menu > summary .bars i{display:block;width:16px;height:2px;border-radius:2px;background:var(--ink);}
.menu[open] > summary{border-color:var(--ink);}
/* Setting display on the panel overrides the UA rule that hides a closed
   <details>'s content, so hide it explicitly or the menu renders permanently
   open on mobile. */
.menu:not([open]) > .menu-panel{display:none;}
.menu-panel{position:absolute;right:0;top:calc(100% + 10px);z-index:40;min-width:222px;
  background:#fff;border:1px solid var(--line);border-radius:14px;padding:9px;
  box-shadow:0 24px 44px -26px rgba(26,22,18,.55);
  display:flex;flex-direction:column;gap:2px;}
.menu-panel a{font-size:15.5px;font-weight:700;color:var(--ink-soft);text-decoration:none;
  padding:12px 14px;border-radius:9px;}
.menu-panel a:hover{background:var(--moss-wash);color:var(--ink);}
.menu-panel a.here{color:var(--ink);background:var(--moss-wash);}
.menu-panel a.cta{margin-top:6px;background:var(--moss);color:#fff;text-align:center;}
.menu-panel a.cta:hover{background:var(--moss-deep);color:#fff;}

.btn{display:inline-block;padding:15px 28px;border-radius:8px;font-weight:800;font-size:15px;
  text-decoration:none;border:2px solid transparent;
  transition:transform .35s var(--ease-expo), box-shadow .35s var(--ease-expo);}
.btn:hover{transform:translateY(-2px);box-shadow:0 10px 26px -16px rgba(26,22,18,.45);}
a.btn-moss{background:var(--moss);color:#fff;}
a.btn-outline{border-color:var(--line);color:var(--ink);}
a.btn-outline:hover{border-color:var(--ink);}
a.btn-white{background:#fff;color:var(--moss-deep);}
@media (prefers-reduced-motion: reduce){
  .btn:hover{transform:none;}
}

/* ---------- home hero ---------- */
.hero{padding:clamp(40px,6vw,76px) 0 clamp(44px,6vw,80px);}
.hero-grid{display:grid;grid-template-columns:1.02fr 0.98fr;gap:clamp(34px,5vw,68px);
  align-items:center;}
h1{font-weight:800;font-size:clamp(43px,5.4vw,72px);line-height:0.99;letter-spacing:-0.034em;
  margin:0 0 24px;max-width:15ch;text-wrap:balance;color:var(--ink);}
h1 .hl{background:linear-gradient(transparent 58%, var(--vivid-hl) 58%);
  padding:0 .04em;border-radius:2px;}
.strands{display:flex;flex-direction:column;gap:15px;max-width:50ch;margin:0 0 30px;}
.strand{position:relative;font-size:clamp(16.5px,1.55vw,18.5px);line-height:1.5;
  color:var(--ink-soft);margin:0;padding-left:24px;}
.strand::before{content:"";position:absolute;left:0;top:.6em;width:9px;height:9px;
  border-radius:50%;background:var(--vivid);}
.strand b{color:var(--ink);font-weight:800;}
.strand .aside{display:block;margin-top:5px;font-size:14px;line-height:1.45;
  color:var(--ink-soft);opacity:.8;}
.ast{color:var(--vivid);font-weight:800;}
.cta-row{display:flex;gap:14px;flex-wrap:wrap;}

/* ---------- the studio shelf ---------- */
.shelf{background:linear-gradient(180deg,#FFFFFF, var(--moss-wash));
  border:1px solid var(--moss-wash-line);border-radius:22px;padding:20px;
  box-shadow:0 2px 0 rgba(255,255,255,.6) inset;}
.shelf-head{display:flex;align-items:baseline;justify-content:space-between;
  margin:4px 6px 15px;}
.shelf-head .lbl{font-size:12px;font-weight:800;letter-spacing:.15em;text-transform:uppercase;
  color:var(--moss);}
.shelf-head .cnt{font-size:12.5px;font-weight:700;color:var(--ink-soft);}
.apps{display:flex;flex-direction:column;gap:10px;}
.appcard{display:flex;align-items:center;gap:15px;background:#fff;
  border:1px solid var(--line);border-radius:15px;padding:12px 15px;text-decoration:none;color:inherit;
  transition:transform .35s var(--ease-expo),box-shadow .35s var(--ease-expo),border-color .35s var(--ease-expo);}
.appcard:hover{transform:translateY(-2px);
  box-shadow:0 18px 32px -22px rgba(26,22,18,.45);border-color:var(--moss-wash-line);}
.tile{flex:none;width:58px;height:58px;border-radius:16px;overflow:hidden;
  box-shadow:0 7px 16px -9px rgba(26,22,18,.55), inset 0 0 0 1px rgba(255,255,255,.16);
  display:flex;align-items:center;justify-content:center;}
.tile img{width:100%;height:100%;object-fit:cover;display:block;}
.tile.cleandone{background:#F4FBF5;} .tile.cleandone img{object-fit:contain;padding:9px;}
.tile.fred{background:#16233F;}
.tile.dest{background:#FFF8F0;}
.tile.primed{background:#101418;color:#fff;font-size:19px;font-weight:800;letter-spacing:-.03em;}
.appmeta{min-width:0;flex:1;}
.appmeta .nm{display:block;font-weight:800;font-size:15.5px;letter-spacing:-.012em;}
.appmeta .ds{display:block;font-size:13px;color:var(--ink-soft);line-height:1.42;margin-top:3px;}
.appmeta .au{font-size:11px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;
  color:var(--moss);margin-top:8px;display:inline-flex;align-items:center;gap:6px;}
.appmeta .au i{width:5px;height:5px;border-radius:50%;background:var(--vivid);display:block;}
.go{flex:none;color:var(--ink-soft);opacity:.4;
  transition:transform .3s var(--ease-expo),opacity .3s var(--ease-expo),color .3s;}
.appcard:hover .go{opacity:1;transform:translateX(3px);color:var(--moss);}
.shelf-foot{margin:14px 6px 4px;font-size:12.5px;font-weight:700;color:var(--ink-soft);
  display:flex;align-items:center;gap:9px;}
.shelf-foot .dot{width:7px;height:7px;border-radius:50%;background:var(--coral);flex:none;}
.shelf-side{margin:15px 6px 2px;padding-top:14px;border-top:1px solid var(--moss-wash-line);}
.side-lbl{font-size:10.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);opacity:.72;margin-bottom:11px;}
.side-apps{display:flex;flex-wrap:wrap;gap:10px 20px;}
.sideapp{display:inline-flex;align-items:center;gap:9px;text-decoration:none;color:var(--ink-soft);
  transition:color .3s var(--ease-expo),transform .3s var(--ease-expo);}
.sideapp:hover{color:var(--ink);transform:translateY(-1px);}
.tile-sm{flex:none;width:30px;height:30px;border-radius:9px;overflow:hidden;
  box-shadow:0 4px 9px -6px rgba(26,22,18,.5), inset 0 0 0 1px rgba(255,255,255,.16);
  display:flex;align-items:center;justify-content:center;}
.tile-sm img{width:100%;height:100%;object-fit:cover;display:block;}
.tile-sm.dest{background:#FFF8F0;}
.tile-sm.primed{background:#101418;color:#fff;font-size:11px;font-weight:800;letter-spacing:-.02em;}
.side-nm{font-size:13px;font-weight:700;letter-spacing:-.008em;}

/* ---------- studio section (home) ---------- */
.studio{background:var(--moss-wash);}
.studio .wrap{padding-top:clamp(44px,6vw,72px);padding-bottom:clamp(44px,6vw,72px);}
.studio-h{font-weight:800;font-size:clamp(26px,2.7vw,36px);letter-spacing:-0.024em;
  margin:0 0 clamp(24px,3vw,36px);line-height:1.04;}
.products{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,2.6vw,30px);
  align-items:start;}
.product{display:flex;flex-direction:column;
  border-top:1px solid var(--moss-wash-line);padding-top:22px;}
.p-head{display:flex;align-items:center;gap:14px;margin-bottom:15px;}
.p-head h3{font-weight:800;font-size:21px;letter-spacing:-0.022em;margin:0;line-height:1.1;}
.p-for{font-size:11px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;
  color:var(--moss);margin-top:5px;display:inline-flex;align-items:center;gap:6px;}
.p-for i{width:5px;height:5px;border-radius:50%;background:var(--vivid);display:block;}
.product > p{font-size:15.5px;line-height:1.6;color:var(--ink-soft);margin:0 0 18px;}
.p-link{font-weight:800;font-size:14.5px;color:var(--moss);text-decoration:none;
  border-bottom:2px solid var(--vivid-wash);padding-bottom:2px;align-self:flex-start;
  transition:border-color .3s var(--ease-expo);}
.p-link:hover{border-color:var(--vivid);}
.p-win{margin-top:24px;}

/* ---------- product screenshots ----------
   Real captures of the real apps. These replaced a set of hand-built fake
   "product windows" on 2026-07-30: they all shared one component, so four
   different products looked identical, which sold the work short.
   Every shot is sized so its UI text stays legible at its display width;
   a screenshot nobody can read is decoration, not proof. */
.shot{background:#fff;border:1px solid var(--moss-wash-line);border-radius:14px;
  overflow:hidden;box-shadow:0 24px 44px -34px rgba(26,22,18,.5);}
.shot img{display:block;width:100%;height:auto;}

/* browser chrome, carried over from the old component, now sitting above a
   real capture and showing the address that app really runs at */
.winbar{display:flex;align-items:center;gap:6px;border-bottom:1px solid var(--line);
  padding:11px 15px;background:#FDFDFB;}
.winbar i{width:9px;height:9px;border-radius:50%;background:var(--line);display:block;}
.winbar i:first-child{background:var(--vivid);}
.winbar .url{margin-left:10px;font-size:12.5px;font-weight:700;color:var(--ink-soft);
  background:var(--moss-wash);border-radius:6px;padding:4px 11px;}
.shot.fred .winbar{background:#17263F;border-bottom-color:#17263F;}
.shot.fred .winbar i{background:rgba(255,255,255,.26);}
.shot.fred .winbar i:first-child{background:#B98A34;}
.shot.fred .winbar .url{background:rgba(255,255,255,.10);color:#E8E2D5;}

/* phone captures get a handset frame instead: CleanDone is a phone-first
   product and a browser bar around it would misrepresent how it is used */
/* widths are set by legibility, not taste: a phone capture is a 393pt screen,
   so displaying it under about 380px starts shrinking its UI text below the
   size it was designed to be read at */
.shot.phone{border-radius:26px;padding:9px;background:#14181D;border-color:#14181D;
  max-width:400px;box-shadow:0 30px 50px -34px rgba(26,22,18,.65);}
.shot.phone img{border-radius:18px;}
.shot.phone.wide{max-width:430px;}
/* on a phone the bezel is wasted width, so drop it and give the capture the
   whole column: it then renders close to life size */
@media(max-width:560px){
  .shot.phone, .shot.phone.wide{max-width:none;padding:0;background:#fff;
    border-color:var(--moss-wash-line);border-radius:16px;}
  .shot.phone img{border-radius:15px;}
}

/* the caption is not decoration: the shots carry demo data, and /values
   promises every number on this site is a real one */
.shot-cap{margin:12px 2px 0;font-size:13px;line-height:1.5;color:var(--ink-soft);}
.shot-wrap{display:flex;flex-direction:column;}
.shot-wrap.centre{align-items:center;}
.shot-wrap.centre .shot-cap{text-align:center;max-width:44ch;}


/* ---------- offer band (home + advisory) ---------- */
.offer{background:var(--moss);color:#fff;}
.offer .wrap{padding-top:clamp(48px,7vw,88px);padding-bottom:clamp(48px,7vw,88px);}
.offer h2{font-weight:800;font-size:clamp(26px,2.7vw,36px);line-height:1.04;
  letter-spacing:-0.024em;margin:0 0 16px;max-width:23ch;text-wrap:balance;}
.offer-lede{font-size:clamp(18px,1.9vw,22px);line-height:1.5;font-weight:700;color:#fff;
  margin:0 0 18px;max-width:46ch;}
.offer p b{color:#fff;}
.offer p{font-size:17px;line-height:1.62;margin:0 0 20px;max-width:55ch;color:#DDE4DA;}
.offer .guarantee{font-size:15px;font-weight:800;color:#fff;margin:0 0 30px;
  display:inline-flex;align-items:center;gap:10px;}
.offer .guarantee i{width:8px;height:8px;border-radius:50%;background:var(--coral);flex:none;}
/* Scoped to prose only. As `.offer a` this matched a.btn-white at equal
   specificity and won on source order, painting white text on the white
   CTA and making the primary button invisible against the moss band. */
.offer p a, .offer li a{color:#fff;}

.proof{padding:clamp(36px,5vw,56px) 0;}
.proof p{font-size:15.5px;color:var(--ink-soft);line-height:1.65;max-width:62ch;margin:0;}

/* ---------- interior page furniture ---------- */
.crumb{font-size:13px;font-weight:700;color:var(--ink-soft);padding-top:6px;}
.crumb a{text-decoration:none;color:var(--ink-soft);}
.crumb a:hover{color:var(--ink);}
.crumb span{opacity:.5;margin:0 8px;}

.phead{padding:clamp(26px,4vw,44px) 0 clamp(28px,4vw,44px);}
.phead h1{font-size:clamp(36px,4.4vw,58px);max-width:18ch;margin-bottom:20px;}
.phead .lede{font-size:clamp(17px,1.8vw,21px);line-height:1.55;color:var(--ink-soft);
  max-width:58ch;margin:0;}
.phead .lede b{color:var(--ink);font-weight:800;}

section.band{padding:clamp(40px,5.5vw,68px) 0;border-top:1px solid var(--line);}
section.band.wash{background:var(--moss-wash);border-top-color:var(--moss-wash-line);}
section.band h2{font-weight:800;font-size:clamp(24px,2.5vw,33px);letter-spacing:-0.024em;
  line-height:1.06;margin:0 0 18px;max-width:24ch;text-wrap:balance;}
section.band h3{font-weight:800;font-size:19px;letter-spacing:-0.02em;margin:0 0 9px;line-height:1.2;}
section.band p{font-size:16.5px;line-height:1.62;color:var(--ink-soft);max-width:62ch;margin:0 0 16px;}
section.band p b{color:var(--ink);font-weight:800;}
section.band p:last-child{margin-bottom:0;}

/* dotted list: the house list shape, typographic rather than carded */
ul.dots{list-style:none;padding:0;margin:0 0 8px;display:flex;flex-direction:column;gap:13px;
  max-width:62ch;}
ul.dots li{position:relative;padding-left:24px;font-size:16.5px;line-height:1.55;color:var(--ink-soft);}
ul.dots li::before{content:"";position:absolute;left:0;top:.58em;width:9px;height:9px;
  border-radius:50%;background:var(--vivid);}
ul.dots li b{color:var(--ink);font-weight:800;}

/* two-column prose grid, hairline-ruled like the studio section */
.cols{display:grid;grid-template-columns:1fr 1fr;gap:clamp(22px,3vw,40px);align-items:start;}
.cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3vw,36px);align-items:start;}
.ruled{border-top:1px solid var(--line);padding-top:20px;}
.wash .ruled{border-top-color:var(--moss-wash-line);}

/* ---------- app page: the identity header ---------- */
.apphead{padding:clamp(28px,4vw,46px) 0 clamp(30px,4vw,50px);}
.apphead-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(30px,4.5vw,60px);
  align-items:center;}
/* the screenshot moved out of the right-hand column and down into its own
   full-width band, because a 1280px capture squeezed into a 540px column
   renders its UI text at about 5px and proves nothing */
.apphead-grid.solo{grid-template-columns:minmax(0,1fr);}
.apphead-grid.solo > div{max-width:62ch;}

.shotband{padding:0 0 clamp(30px,4.5vw,52px);}
.apphead .idrow{display:flex;align-items:center;gap:18px;margin-bottom:22px;}
.tile-lg{flex:none;width:76px;height:76px;border-radius:21px;overflow:hidden;
  box-shadow:0 10px 22px -12px rgba(26,22,18,.55), inset 0 0 0 1px rgba(255,255,255,.16);
  display:flex;align-items:center;justify-content:center;}
.tile-lg img{width:100%;height:100%;object-fit:cover;display:block;}
.tile-lg.cleandone{background:#F4FBF5;} .tile-lg.cleandone img{object-fit:contain;padding:12px;}
.tile-lg.fred{background:#16233F;}
.tile-lg.dest{background:#FFF8F0;}
.tile-lg.primed{background:#101418;color:#fff;font-size:26px;font-weight:800;letter-spacing:-.04em;}
.apphead h1{font-size:clamp(34px,4vw,52px);margin:0;max-width:none;}
.apphead .who{font-size:12px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;
  color:var(--moss);margin-top:8px;display:inline-flex;align-items:center;gap:7px;}
.apphead .who i{width:6px;height:6px;border-radius:50%;background:var(--vivid);display:block;}

/* status line: honest state of each app, no badge chrome */
.status{font-size:14.5px;font-weight:700;color:var(--ink-soft);margin:0 0 26px;
  display:inline-flex;align-items:center;gap:9px;}
.status i{width:8px;height:8px;border-radius:50%;background:var(--vivid);flex:none;}
.status.building i{background:var(--coral);}

/* ---------- support: the block Apple actually reads ---------- */
.supportcard{border:1px solid var(--line);border-radius:16px;padding:clamp(22px,3vw,30px);
  background:#fff;max-width:none;}
.wash .supportcard{border-color:var(--moss-wash-line);}
.supportcard h3{margin-bottom:12px;}
.supportcard .addr{display:inline-flex;align-items:center;gap:11px;font-weight:800;
  font-size:clamp(18px,2vw,24px);letter-spacing:-0.02em;color:var(--moss);text-decoration:none;
  border-bottom:2px solid var(--vivid-wash);padding-bottom:3px;
  transition:border-color .3s var(--ease-expo);word-break:break-word;}
.supportcard .addr:hover{border-color:var(--vivid);}
.supportcard .note{font-size:14.5px;color:var(--ink-soft);line-height:1.55;margin:14px 0 0;}

/* support hub: one row per app, its own address on it */
.supportlist{display:flex;flex-direction:column;gap:14px;}
.supportrow{display:grid;grid-template-columns:auto 1fr auto;gap:18px;align-items:center;
  border:1px solid var(--line);border-radius:15px;padding:16px 18px;background:#fff;}
.wash .supportrow{border-color:var(--moss-wash-line);}
.supportrow .nm{font-weight:800;font-size:16.5px;letter-spacing:-.015em;}
.supportrow .ds{font-size:13.5px;color:var(--ink-soft);line-height:1.45;margin-top:3px;}
.supportrow .mail{font-weight:800;font-size:15px;color:var(--moss);text-decoration:none;
  border-bottom:2px solid var(--vivid-wash);padding-bottom:2px;white-space:nowrap;
  transition:border-color .3s var(--ease-expo);}
.supportrow .mail:hover{border-color:var(--vivid);}

/* ---------- about: the two of us ---------- */
/* stretch, not start: the two bios are different lengths, so without this the
   "Building" rows start at different heights and the pair reads as misaligned */
.people{display:grid;grid-template-columns:1fr 1fr;gap:clamp(26px,4vw,52px);align-items:stretch;}
.person{display:flex;flex-direction:column;}
.portrait{width:clamp(150px,17vw,196px);height:clamp(150px,17vw,196px);border-radius:22px;
  overflow:hidden;background:var(--moss-wash);margin-bottom:20px;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 14px 30px -20px rgba(26,22,18,.55);}
.portrait img{width:100%;height:100%;object-fit:cover;display:block;}
/* monogram fallback: deliberate, not a broken image, until a photo lands */
.portrait .mono{font-weight:800;font-size:clamp(44px,5vw,60px);letter-spacing:-.05em;
  color:var(--moss);}
.person h3{font-weight:800;font-size:23px;letter-spacing:-0.022em;margin:0 0 5px;line-height:1.15;}
.person .role{font-size:12px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;
  color:var(--moss);margin:0 0 16px;display:inline-flex;align-items:center;gap:7px;}
.person .role i{width:6px;height:6px;border-radius:50%;background:var(--vivid);display:block;}
.person p{font-size:16px;line-height:1.62;color:var(--ink-soft);margin:0 0 14px;max-width:46ch;}

/* ---------- values ----------
   Editorial rather than carded: a big numeral, the word at display size, and
   the body opposite, separated by hairline rules. Card grids of values are
   exactly the uniform-icon-card pattern PRODUCT.md bans. */
.values{display:flex;flex-direction:column;gap:clamp(30px,3.6vw,46px);}
.value{border-top:1px solid var(--line);padding-top:clamp(20px,2.4vw,28px);
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);gap:clamp(18px,3vw,48px);
  align-items:start;}
.wash .value{border-top-color:var(--moss-wash-line);}
.v-num{font-size:12px;font-weight:800;letter-spacing:.16em;color:var(--moss);
  margin-bottom:10px;font-variant-numeric:tabular-nums;}
.value h3{font-weight:800;font-size:clamp(30px,3.8vw,48px);letter-spacing:-0.032em;
  margin:0;line-height:1.02;color:var(--ink);}
.value h3 em{font-style:normal;color:var(--moss);}
.value p{margin:0 0 16px;font-size:clamp(16.5px,1.6vw,18px);line-height:1.6;
  color:var(--ink-soft);max-width:52ch;}
.value p:last-child{margin-bottom:0;}
.value .refuse{font-size:15.5px;font-weight:800;color:var(--ink);margin:0;
  display:flex;align-items:flex-start;gap:11px;line-height:1.5;max-width:48ch;}
.value .refuse i{width:8px;height:8px;border-radius:50%;background:var(--coral);flex:none;
  margin-top:.42em;}

/* ---------- about: what each of us brings ---------- */
/* auto pushes this to the foot of its column so both rows sit on one line */
.brings{margin:24px 0 0;margin-top:auto;padding-top:18px;
  border-top:1px solid var(--moss-wash-line);}
.brings .k{font-size:11px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--moss);margin-bottom:10px;}
.chips{display:flex;flex-wrap:wrap;gap:8px;}
/* a working link per app, not decorative badges: these go somewhere */
.chip{display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  font-size:13.5px;font-weight:700;color:var(--ink);
  border:1px solid var(--moss-wash-line);background:#fff;border-radius:999px;padding:7px 14px 7px 8px;
  transition:border-color .3s var(--ease-expo),transform .3s var(--ease-expo);}
.chip:hover{border-color:var(--moss);transform:translateY(-1px);}
.chip .tile-sm{width:22px;height:22px;border-radius:7px;box-shadow:none;}
.chip .tile-sm.cleandone{background:#F4FBF5;}
.chip .tile-sm.cleandone img{object-fit:contain;padding:3px;}
.chip .tile-sm.fred{background:#16233F;}
.chip .tile-sm.primed{background:#101418;font-size:9px;}


/* ---------- contact ---------- */
.contact-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(26px,4vw,56px);
  align-items:start;}
.detail{border-top:1px solid var(--line);padding-top:16px;margin-bottom:22px;}
.detail .k{font-size:11.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--moss);margin-bottom:7px;}
.detail .v{font-size:16px;line-height:1.55;color:var(--ink-soft);}
.detail .v a{font-weight:700;color:var(--moss);text-decoration:none;
  border-bottom:2px solid var(--vivid-wash);padding-bottom:1px;}
.detail .v a:hover{border-bottom-color:var(--vivid);}

/* ---------- footer ---------- */
footer{background:var(--ink);color:#fff;}
footer .wrap{padding-top:44px;padding-bottom:34px;}
.foot-top{display:grid;grid-template-columns:1.1fr 2fr;gap:clamp(28px,4vw,56px);
  padding-bottom:32px;border-bottom:1px solid rgba(255,255,255,.13);}
.foot-blurb{font-size:14.5px;line-height:1.6;color:rgba(255,255,255,.62);margin:16px 0 0;
  max-width:34ch;}
.foot-nav{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}
.foot-nav h2{font-size:11.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.5);margin:0 0 14px;}
.foot-nav ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:10px;}
.foot-nav a{font-size:14.5px;font-weight:700;color:rgba(255,255,255,.86);text-decoration:none;}
.foot-nav a:hover{color:#fff;text-decoration:underline;}
.foot-bottom{padding-top:26px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;}
footer .fine{font-size:13px;color:rgba(255,255,255,.55);line-height:1.6;max-width:62ch;}
footer .fine a{color:rgba(255,255,255,.78);}

/* ---------- motion ----------
   Scroll reveal. Hiding is opt-in per element: JS adds .reveal-hidden only to
   sections that start below the fold, so nothing above the fold ever depends
   on a transition running to become visible. No JS, no observer, reduced
   motion, a thrown error: the page is simply all visible. That asymmetry is
   deliberate. A reveal effect must never be able to hide content. */
[data-reveal].reveal-hidden{opacity:0;transform:translateY(20px);}
[data-reveal].reveal-hidden > *{opacity:0;transform:translateY(12px);}
[data-reveal].reveal-in{opacity:1;transform:none;
  transition:opacity .7s var(--ease-expo), transform .7s var(--ease-expo);}
[data-reveal].reveal-in > *{opacity:1;transform:none;
  transition:opacity .6s var(--ease-expo), transform .6s var(--ease-expo);}
[data-reveal].reveal-in > *:nth-child(2){transition-delay:.07s;}
[data-reveal].reveal-in > *:nth-child(3){transition-delay:.13s;}
[data-reveal].reveal-in > *:nth-child(4){transition-delay:.19s;}
[data-reveal].reveal-in > *:nth-child(n+5){transition-delay:.24s;}
/* The instant escape hatch. Used by the script's backstop when the environment
   never runs intersection callbacks, and it must not depend on a transition:
   in a context that isn't painting, a transition never advances, so handing
   visibility to one would leave the content at opacity 0 for good. */
[data-reveal].reveal-now,
[data-reveal].reveal-now > *{opacity:1 !important;transform:none !important;
  transition:none !important;}

@media (prefers-reduced-motion: reduce){
  [data-reveal].reveal-hidden,
  [data-reveal].reveal-hidden > *,
  [data-reveal].reveal-in,
  [data-reveal].reveal-in > *{opacity:1;transform:none;transition:none;}
}

@media (prefers-reduced-motion: no-preference){
  .rise{animation:rise .9s var(--ease-expo) both;}
  .rise.d1{animation-delay:.08s;} .rise.d2{animation-delay:.16s;}
  .rise.d3{animation-delay:.26s;}
  @keyframes rise{from{opacity:0;transform:translateY(22px);}to{opacity:1;transform:none;}}
  .apps .appcard{animation:cardin .7s var(--ease-expo) both;}
  .apps .appcard:nth-child(1){animation-delay:.34s;}
  .apps .appcard:nth-child(2){animation-delay:.42s;}
  .apps .appcard:nth-child(3){animation-delay:.50s;}
  .shelf-side{animation:cardin .7s var(--ease-expo) both;animation-delay:.54s;}
  @keyframes cardin{from{opacity:0;transform:translateY(10px) scale(.985);}to{opacity:1;transform:none;}}
}

/* ---------- touch targets ----------
   WCAG 2.5.8 wants 24x24 minimum, and PRODUCT.md asks for comfortable targets
   because this audience lives on phones. Two techniques, picked per element:
   real padding where there is room in the layout, and an invisible expanded
   hit area where padding would move a border-bottom underline off its text.
   The pseudo-element is only used on links with no close vertical neighbour,
   so expanded areas never overlap and steal each other's taps. */
@media (max-width: 900px), (pointer: coarse){
  .p-link, .mail, .addr, .sideapp, .wm, .chip{position:relative;}
  .p-link::after, .mail::after, .addr::after, .sideapp::after, .wm::after, .chip::after{
    content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
    height:44px;min-height:100%;}
  /* stacked footer links get real padding instead: they sit close together,
     so an expanded overlay would overlap the neighbour above and below */
  .foot-nav ul{gap:2px;}
  .foot-nav a{display:block;padding:10px 0;}
  .crumb a{display:inline-block;padding:6px 0;}
  /* the per-app addresses on /contact are list items, not prose links */
  .supportcard ul.dots a{display:inline-block;padding:6px 0;}
}

/* ---------- responsive ---------- */
@media(max-width:900px){
  .hero-grid{grid-template-columns:1fr;gap:40px;}
  .products{grid-template-columns:1fr;gap:22px;}
  .apphead-grid{grid-template-columns:1fr;gap:34px;}
  .cols,.contact-grid,.people{grid-template-columns:1fr;gap:30px;}
  .cols3{grid-template-columns:1fr;gap:26px;}
  .value{grid-template-columns:1fr;gap:14px;}
  .value h3{max-width:none;}
  .foot-top{grid-template-columns:1fr;gap:30px;}
}
@media(max-width:820px){
  .navlinks{display:none;}
  .menu{display:block;}
}
@media(max-width:760px){
  .supportrow{grid-template-columns:auto 1fr;row-gap:12px;}
  .supportrow .mail{grid-column:1 / -1;white-space:normal;justify-self:start;}
  .foot-nav{grid-template-columns:1fr 1fr;gap:22px;}
}
@media(max-width:420px){
  .foot-nav{grid-template-columns:1fr;}
}
