
/* ═══ Rylo HQ ═══════════════════════════════════════════════════════════
   Palette: Cyan. Every colour is a token; nothing below hardcodes a hex
   outside :root, so a palette change is one block.
   ══════════════════════════════════════════════════════════════════════ */

/* Variable fonts: ONE file each, with a weight RANGE. Shipping a file per
   weight is the usual mistake and it is pure waste — Google serves the same
   bytes for every weight of a variable family. */
@font-face{font-family:'Archivo';src:url('/assets/fonts/archivo.woff2') format('woff2');
  font-weight:400 800;font-style:normal;font-display:swap;}
@font-face{font-family:'Inter';src:url('/assets/fonts/inter.woff2') format('woff2');
  font-weight:100 900;font-style:normal;font-display:swap;}

:root{
  --ground:#0A1216; --surface:#111C22; --raised:#17262E; --line:#1E313B;
  --ink:#EAF4F7; --muted:#8DA3AC; --faint:#7A93A0;
  --acc:#22D3EE; --acc-dim:#0E7F92; --on-acc:#0A1216;
  --disp:'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --body:'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --w:1180px; --gut:clamp(20px,4vw,40px);
  --r:10px;
}
*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
/* `clip`, not `hidden` — hidden turns these into scroll containers and a
   sticky header inside a scroll container never sticks. Both elements, or
   body's clip just propagates and html still reports the wider box. */
html,body{overflow-x:clip;max-width:100%;}
body{margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--body);font-size:16.5px;line-height:1.7;
  -webkit-font-smoothing:antialiased;}
img,svg{max-width:100%;}
a{color:inherit;}

.w{max-width:var(--w);margin:0 auto;padding:0 var(--gut);}
.narrow{max-width:760px;}

h1,h2,h3,h4{font-family:var(--disp);font-weight:700;letter-spacing:-.028em;
  line-height:1.08;margin:0;text-wrap:balance;}
h1{font-size:clamp(38px,6.2vw,66px);}
h2{font-size:clamp(27px,3.9vw,42px);letter-spacing:-.026em;}
h3{font-size:clamp(19px,2.2vw,23px);letter-spacing:-.018em;line-height:1.24;}
p{margin:0 0 1.05em;max-width:66ch;}
.lede{font-size:clamp(17px,1.9vw,20px);line-height:1.68;color:var(--muted);max-width:60ch;}
.kick{font-family:var(--disp);font-weight:700;font-size:12px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--acc);margin:0 0 14px;}
.muted{color:var(--muted);}
strong,b{font-weight:640;color:var(--ink);}

.skip{position:absolute;left:-9999px;top:0;z-index:100;padding:12px 18px;
  background:var(--acc);color:var(--on-acc);font-weight:700;}
.skip:focus{left:8px;top:8px;}
:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:3px;}

/* ── buttons ─────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:46px;padding:12px 24px;border-radius:5px;text-decoration:none;
  font-family:var(--disp);font-weight:700;font-size:13.5px;letter-spacing:.09em;
  text-transform:uppercase;white-space:nowrap;border:1px solid transparent;
  transition:background-color .2s,border-color .2s,color .2s,transform .2s;}
.btn-a{background:var(--acc);color:var(--on-acc);}
.btn-a:hover{transform:translateY(-1px);filter:brightness(1.07);}
.btn-b{border-color:var(--line);color:var(--ink);}
.btn-b:hover{border-color:var(--acc);color:var(--acc);}
.btn:active{transform:none;}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px;}

/* ── nav ─────────────────────────────────────────────────────────────── */
.nav{position:sticky;top:0;z-index:50;background:color-mix(in srgb,var(--ground) 88%,transparent);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--line);}
.nav-in{max-width:var(--w);margin:0 auto;padding:0 var(--gut);height:78px;
  display:flex;align-items:center;gap:20px;}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none;margin-right:auto;
  position:relative;}
/* Fireflies over the whole lockup.

   Each point is its own element with its own size, position, duration and
   delay — deliberately non-repeating numbers, because anything that lines up
   starts reading as a pulse. They stay off until .lit, which the nav sets once
   the hero is behind you. */
.flies{position:absolute;inset:-13px -9px;pointer-events:none;z-index:-1;
  opacity:0;transition:opacity 1.1s ease;}
.nav.lit .flies{opacity:1;}
.flies i{position:absolute;border-radius:50%;
  background:radial-gradient(closest-side,
    color-mix(in srgb,var(--acc) 72%,transparent),
    color-mix(in srgb,var(--acc) 28%,transparent) 48%, transparent 78%);
  filter:blur(14px);
  /* The animation runs ALWAYS, not only when lit. Gating it on .lit meant
     removing the class killed the animation mid-cycle and every field snapped
     to its base state — which is why it vanished instead of fading. Visibility
     is the container's job alone. */
  animation-name:fly;animation-iteration-count:infinite;
  animation-timing-function:ease-in-out;}
@keyframes fly{
  0%,100%{opacity:.14; transform:scale(.86)}
  21%    {opacity:.92; transform:scale(1.10)}
  39%    {opacity:.34; transform:scale(.94)}
  58%    {opacity:.74; transform:scale(1.05)}
  77%    {opacity:.20; transform:scale(.90)}
}
/* A soft bed under the whole lockup so the individual points read as one
   living clump rather than as separate dots. */
.brand::before{content:"";position:absolute;inset:-11px -8px;pointer-events:none;
  z-index:-2;opacity:0;transition:opacity 1.1s ease;border-radius:44px;
  background:radial-gradient(72% 130% at 40% 50%,
    color-mix(in srgb,var(--acc) 30%,transparent), transparent 74%);
  filter:blur(11px);}
.nav.lit .brand::before{opacity:1;animation:bed 9s ease-in-out infinite;}
@keyframes bed{0%,100%{opacity:.55}43%{opacity:1}71%{opacity:.7}}

@media(prefers-reduced-motion:reduce){
  /* Keep the light, lose the flicker. The movement is the vestibular part;
     the glow itself is not. */
  .flies i{animation:none;opacity:.5;}
  .nav.lit .brand::before{animation:none;opacity:.85;}
}
.brand-name{font-family:var(--disp);font-weight:800;font-size:21px;letter-spacing:-.03em;}
.brand-name em{font-style:normal;font-weight:300;color:var(--muted);margin-left:5px;}
.nav-links{display:flex;gap:4px;}
.nav-links a{padding:9px 14px;border-radius:5px;text-decoration:none;
  font-family:var(--disp);font-weight:600;font-size:13.5px;letter-spacing:.06em;
  color:var(--muted);transition:color .2s,background-color .2s;}
.nav-links a:hover{color:var(--ink);background:var(--surface);}
.nav-links a[aria-current="page"]{color:var(--acc);}
.burger{display:none;width:44px;height:44px;border:0;background:none;cursor:pointer;
  flex-direction:column;gap:5px;align-items:center;justify-content:center;padding:0;}
.burger span{display:block;width:22px;height:2px;background:var(--ink);
  transition:transform .28s,opacity .2s;}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0;}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}
@media(max-width:880px){
  .burger{display:flex;}
  .nav-cta{display:none;}
  .nav-links{display:none;position:absolute;top:100%;left:0;right:0;flex-direction:column;
    gap:0;padding:8px var(--gut) 18px;background:var(--ground);
    border-bottom:1px solid var(--line);}
  .nav-links.open{display:flex;}
  .nav-links a{padding:14px 6px;font-size:15px;border-bottom:1px solid var(--line);}
  .nav-links a:last-child{border-bottom:0;}
}

/* ── sections ────────────────────────────────────────────────────────── */
.sec{padding:clamp(58px,8.5vh,104px) 0;}
.sec--alt{background:var(--surface);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);}
.sec-head{max-width:62ch;margin-bottom:38px;}
.sec-head p{color:var(--muted);}

/* ── hero ────────────────────────────────────────────────────────────── */
.hero{position:relative;overflow:hidden;display:flex;align-items:center;
  /* Fill what is left of the viewport under the 78px header, so the h1 owns
     the first screen and the next section is a deliberate scroll rather than
     something peeking over the fold. svh, not vh — on mobile Safari vh is the
     tallest the viewport ever gets, which pushes content under the URL bar. */
  min-height:calc(100svh - 78px);
  padding:clamp(48px,7vh,90px) 0 clamp(96px,14vh,150px);}
/* Scroll hint, so an almost-empty first screen still reads as "there is more" */
.hero-cue{position:absolute;left:50%;bottom:34px;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:8px;
  font-family:var(--disp);font-weight:600;font-size:10.5px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--faint);pointer-events:none;}
.hero-cue i{display:block;width:1px;height:30px;
  background:linear-gradient(var(--faint),transparent);
  animation:cue 2.4s ease-in-out infinite;transform-origin:top;}
@keyframes cue{0%,100%{transform:scaleY(.45);opacity:.45}50%{transform:scaleY(1);opacity:1}}
@media(prefers-reduced-motion:reduce){.hero-cue i{animation:none;}}
.hero::after{content:"";position:absolute;top:-30%;right:-8%;width:52%;height:150%;
  background:radial-gradient(closest-side,color-mix(in srgb,var(--acc) 15%,transparent),transparent);
  pointer-events:none;z-index:-1;}
.hero h1{max-width:17ch;}
.hero .lede{margin-top:20px;}
.phero{padding:clamp(58px,9vh,104px) 0 clamp(34px,4.5vh,54px);
  border-bottom:1px solid var(--line);}
.phero h1{max-width:19ch;}

/* ── cards ───────────────────────────────────────────────────────────── */
.grid{display:grid;gap:18px;grid-template-columns:1fr;}
@media(min-width:720px){.grid-2{grid-template-columns:1fr 1fr;}}
@media(min-width:900px){.grid-3{grid-template-columns:repeat(3,1fr);}}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:26px 26px 28px;transition:border-color .22s,transform .22s;}
.card:hover{border-color:color-mix(in srgb,var(--acc) 45%,var(--line));}
.card .num{font-family:var(--disp);font-weight:800;font-size:12px;letter-spacing:.2em;
  color:var(--acc);display:block;margin-bottom:12px;}
.card h3{margin-bottom:9px;}
.card p{color:var(--muted);font-size:15px;margin:0;}
.card ul{margin:14px 0 0;padding:0;list-style:none;}
.card li{position:relative;padding-left:20px;color:var(--muted);font-size:14.5px;
  line-height:1.62;margin-bottom:7px;}
.card li::before{content:"";position:absolute;left:2px;top:9px;width:6px;height:6px;
  border-radius:50%;background:var(--acc-dim);}
a.card{text-decoration:none;display:block;}
a.card:hover{transform:translateY(-2px);}
.card-go{display:inline-flex;align-items:center;gap:7px;margin-top:16px;
  font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--acc);}

/* ── numbered process ────────────────────────────────────────────────── */
.steps{counter-reset:s;list-style:none;padding:0;margin:26px 0 0;max-width:64ch;}
.steps li{counter-increment:s;position:relative;padding-left:52px;margin-bottom:22px;
  color:var(--muted);}
.steps li::before{content:counter(s,decimal-leading-zero);position:absolute;left:0;top:1px;
  font-family:var(--disp);font-weight:800;font-size:14px;letter-spacing:.06em;
  color:var(--acc);background:var(--surface);border:1px solid var(--line);
  width:34px;height:34px;border-radius:50%;display:grid;place-items:center;}
.steps b{display:block;color:var(--ink);font-family:var(--disp);font-weight:700;
  font-size:17.5px;letter-spacing:-.012em;margin-bottom:3px;}

/* ── price ───────────────────────────────────────────────────────────── */
.price{display:flex;align-items:baseline;gap:9px;margin:4px 0 16px;flex-wrap:wrap;}
.price .n{font-family:var(--disp);font-weight:800;font-size:clamp(32px,4.4vw,44px);
  letter-spacing:-.04em;color:var(--ink);line-height:1;}
.price .per{font-size:14px;color:var(--faint);}
.price .note{width:100%;font-size:13.5px;color:var(--faint);margin-top:2px;}

/* ── work / case studies ─────────────────────────────────────────────── */
.case{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:28px 28px 30px;}
.case-top{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  margin-bottom:14px;}
/* Let the heading wrap rather than the tag dropping to its own line — a
   long name plus a long tag was breaking the alignment between cards. */
.case-top > div{min-width:0;}
.case-top .tag{flex:0 0 auto;}
@media(max-width:520px){.case-top{flex-direction:column;}}
.case h3{font-size:clamp(21px,2.6vw,26px);}
.tag{font-family:var(--disp);font-weight:700;font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;padding:5px 11px;border-radius:99px;white-space:nowrap;
  border:1px solid var(--line);color:var(--faint);}
.tag--client{color:var(--acc);border-color:color-mix(in srgb,var(--acc) 40%,transparent);}
.tag--own{color:var(--muted);}
.case dl{margin:18px 0 0;display:grid;gap:14px;}
.case dt{font-family:var(--disp);font-weight:700;font-size:11.5px;letter-spacing:.17em;
  text-transform:uppercase;color:var(--faint);margin-bottom:4px;}
.case dd{margin:0;color:var(--muted);font-size:15px;line-height:1.72;}
.facts{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px;list-style:none;padding:0;}
.facts li{font-size:13px;color:var(--muted);background:var(--raised);
  border:1px solid var(--line);border-radius:99px;padding:6px 13px;}
.case-visit{display:inline-flex;align-items:center;gap:7px;margin-top:20px;
  min-height:26px;text-decoration:none;color:var(--acc);
  font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:.11em;
  text-transform:uppercase;border-bottom:1px solid transparent;transition:border-color .2s;}
.case-visit:hover{border-bottom-color:var(--acc);}

/* ── legal ───────────────────────────────────────────────────────────── */
.legal h2{font-size:clamp(20px,2.4vw,25px);margin:44px 0 12px;}
.legal h2:first-of-type{margin-top:0;}
.legal p,.legal li{color:var(--muted);max-width:68ch;}
.legal a{color:var(--acc);text-decoration:underline;text-underline-offset:3px;}
.legal ul{padding-left:20px;}
.legal li{margin-bottom:8px;}

/* ── footer ──────────────────────────────────────────────────────────── */
.site-foot{background:var(--surface);border-top:1px solid var(--line);
  padding:clamp(48px,7vh,74px) 0 0;margin-top:clamp(40px,6vh,70px);}
.f-grid{display:grid;gap:36px 28px;grid-template-columns:1fr;padding-bottom:44px;}
@media(min-width:760px){.f-grid{grid-template-columns:1.6fr 1fr 1fr 1.2fr;}}
.f-brand .logo{display:block;margin-bottom:14px;}
.f-tag{color:var(--muted);font-size:14.5px;line-height:1.72;max-width:34ch;margin:0 0 10px;}
.f-based{color:var(--faint);font-size:13.5px;margin:0;}
.f-h{font-family:var(--disp);font-weight:700;font-size:11.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--faint);margin:0 0 14px;}
.f-col ul{list-style:none;margin:0;padding:0;}
.f-col li{margin-bottom:2px;}
.f-col a{display:inline-flex;align-items:center;min-height:28px;padding:3px 0;
  color:var(--muted);text-decoration:none;font-size:14.5px;transition:color .2s;}
.f-col a:hover{color:var(--acc);}
.f-bar{border-top:1px solid var(--line);padding:18px 0 24px;display:flex;
  justify-content:space-between;gap:14px;flex-wrap:wrap;
  font-size:13px;color:var(--faint);}
.f-legal{display:flex;gap:18px;}
.f-legal a{color:var(--faint);text-decoration:none;
  display:inline-flex;align-items:center;min-height:26px;}
.f-legal a:hover{color:var(--acc);}

/* Tap targets — WCAG 2.2 SC 2.5.8 wants 24x24 for anything standing alone.
   Links inside a sentence are exempt and are deliberately left alone. */
.facts a{display:inline-flex;align-items:center;min-height:26px;}
.legal li > a:only-child,
.sec p > a:only-child{display:inline-flex;align-items:center;min-height:26px;}

/* ── reveal on scroll ────────────────────────────────────────────────── */
.rise{opacity:0;transform:translateY(20px);
  transition:opacity .7s cubic-bezier(.16,1,.3,1) var(--d,0ms),
             transform .7s cubic-bezier(.16,1,.3,1) var(--d,0ms);}
.rise.in{opacity:1;transform:none;}
@media(prefers-reduced-motion:reduce){
  /* Scoped, not blanket. A blanket !important kill-switch beats every
     specific rule written afterwards and is how reduced-motion users end up
     with a page that looks broken rather than calm. */
  .rise{opacity:1;transform:none;transition:none;}
  .btn:hover,a.card:hover{transform:none;}
  *{scroll-behavior:auto !important;}
}
