/* FlockFactor. One grammar from top to bottom: an object, a hairline cut to it, its name and one
   sentence. Two grounds, Paper and Ink. One orange, in three tones, each measured for the ground
   it stands on. Nothing on this page sits in a card. */
:root{
  color-scheme:light;
  --page:#EBEBE8; --ink:#0A0A0B; --ink-2:#55555A; --mute:#67676C; --rule:#D6D6D2;
  --accent:#C2552A;      /* a mark on Paper, 3.8:1, never text */
  --accent-ink:#A9461F;  /* orange carrying small text on Paper, 4.9:1 */
  --accent-lit:#F07A3C;  /* orange on Ink, 7.1:1, and the flood inside a button */
  --on-ink:#F5F5F1; --on-ink-2:rgba(245,245,241,.7); --on-ink-3:rgba(245,245,241,.52); --rule-ink:rgba(245,245,241,.16);
  --pad:clamp(20px,3.6vw,72px);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-soft:cubic-bezier(.4,0,.2,1);
  --disp:"Bricolage Grotesque","Mona Sans",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
  --mark:8px; --markgap:9px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:76px}
body{background:var(--page);color:var(--ink);font:400 16px/1.5 "Mona Sans",system-ui,sans-serif;-webkit-font-smoothing:antialiased;overflow-x:clip}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
ul,ol{list-style:none}
::selection{background:rgba(194,85,42,.24);color:var(--ink)}
.wrap{width:100%;max-width:1720px;margin-inline:auto;padding-inline:var(--pad)}
.mono{font-family:var(--mono);font-size:11.5px;line-height:1.4;letter-spacing:.055em;text-transform:uppercase}
.nb{white-space:nowrap}
/* the accent full stop, drawn rather than typed so it can be the accent on any ground */
.stop{display:inline-block;width:.17em;height:.17em;margin-left:.045em;border-radius:50%;background:var(--accent)}
.on-ink .stop{background:var(--accent-lit)}
.skip{position:absolute;left:var(--pad);top:-60px;z-index:60;background:var(--ink);color:var(--on-ink);padding:14px 16px;border-radius:4px}
.skip:focus{top:12px}
:focus-visible{outline:2px solid var(--ink);outline-offset:4px;border-radius:2px}
.on-ink :focus-visible{outline-color:var(--on-ink)}

/* ---- the button ----
   A block of Ink with the brand's full stop closing the label. Pointing at it floods the block
   from that stop, and the label goes to Ink. No circle, no porthole, nothing drawn inside it.
   The flood is a DISC THAT SCALES, clipped by the button. It used to be an animated clip-path,
   which the browser repaints on the main thread every frame: it hitched part way through, most
   visibly on the way back. A transform is carried by the compositor and cannot.
   The fill is --flood: the lit orange everywhere except on the orange band, where an orange fill
   would lose the button's edge, so there it is Paper. Same motion, same timing, either way. */
.btn{--h:52px;--px:24px;--dot:7px;position:relative;isolation:isolate;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--h);padding:0 var(--px);border:0;border-radius:4px;background:var(--ink);color:var(--on-ink);cursor:pointer;
  font-family:var(--mono);font-size:12.5px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;line-height:1;white-space:nowrap;
  /* the label changes colour as the flood's edge crosses its middle: .2s into the way back, .05s into
     the way in. Changed at once on the way back, it sat Paper on a Paper flood and vanished. */
  transition:color .14s var(--ease-soft) .2s,transform .2s var(--ease-out)}
.btn__x{display:inline}
.btn::before{content:"";position:absolute;z-index:-1;left:calc(100% - var(--px) - var(--dot) / 2);top:58%;width:240%;aspect-ratio:1;border-radius:50%;
  background:var(--flood,var(--accent-lit));transform:translate3d(-50%,-50%,0) scale(0);will-change:transform;
  transition:transform .5s cubic-bezier(.4,0,.2,1)}
.btn i{flex:none;width:var(--dot);height:var(--dot);margin-left:3px;border-radius:50%;background:var(--accent-lit);align-self:center;transform:translateY(3px);transition:background-color .2s var(--ease-soft)}
.btn--sm{--h:44px;--px:18px;--dot:6px;font-size:12px}
.btn--paper{background:var(--on-ink);color:var(--ink)}
.btn--paper i{background:var(--accent)}
.band--signal .btn{--flood:var(--on-ink)}
.btn:focus-visible{outline-offset:3px}
.btn:active{transform:scale(.985)}
.btn:active::before,.btn:focus-visible::before{transform:translate3d(-50%,-50%,0) scale(1);transition:transform .7s cubic-bezier(.3,.7,.15,1)}
.btn:active,.btn:focus-visible{color:var(--ink);transition:color .16s var(--ease-soft) .05s,transform .2s var(--ease-out)}
.btn:active i,.btn:focus-visible i{background:var(--ink)}
.band--signal .btn:active i,.band--signal .btn:focus-visible i{background:var(--accent)}
.btn[disabled]{opacity:.6;cursor:default}
@media (hover:hover) and (pointer:fine){
  .btn:hover{color:var(--ink);transition:color .16s var(--ease-soft) .05s,transform .2s var(--ease-out)}
  .btn:hover::before{transform:translate3d(-50%,-50%,0) scale(1);transition:transform .7s cubic-bezier(.3,.7,.15,1)}
  .btn:hover i{background:var(--ink)}
  .band--signal .btn:hover i{background:var(--accent)}
}
/* the text link: an accent underline that draws from the left and leaves to the right */
.lnk{position:relative;display:inline-block;padding:6px 0}
.lnk::after{content:"";position:absolute;left:0;right:0;bottom:2px;height:1.5px;background:var(--accent);transform:scaleX(0);transform-origin:right;transition:transform .3s var(--ease-out)}
.on-ink .lnk::after{background:var(--accent-lit)}
.lnk:focus-visible::after,.lnk.is-on::after{transform:scaleX(1);transform-origin:left}
@media (hover:hover) and (pointer:fine){.lnk:hover::after{transform:scaleX(1);transform-origin:left}}

/* ================= the first screen ================= */
.hero{background-image:linear-gradient(128.9deg,rgba(255,255,255,.95) 0%,rgba(255,255,255,0) 46%,rgba(122,51,23,.075) 100%)}
.hero__in{min-height:100svh;display:flex;flex-direction:column;justify-content:space-between;
  /* Every band of the first screen's height, named once and spent twice: by the rule that uses
     it, and by --fith, which subtracts them all to find what is left for a photograph. A single
     magic constant here is what makes a first screen a few pixels taller than its window. */
  --hd:80px;
  --eyeh:calc(16px + clamp(12px,1.8vh,22px));
  --h1pt:clamp(4px,1.2vh,16px);
  --ixmt:clamp(22px,3.6vh,44px); --ixh:59px;
  --shpt:clamp(20px,3.4vh,44px); --shrg:clamp(14px,2vh,22px); --caph:104px; --shpb:clamp(28px,4.6vh,56px);
  --fs:min(clamp(38px,6.35vw,124px),12.5vh);
  --g:clamp(24px,3.2vw,64px);
  --col:225px;
  --avail:calc(min(100vw,1720px) - 2 * var(--pad) - 2 * var(--g));
  /* widest tablet the row can carry: no column floored, the phone floored, phone and box floored */
  --fitw:min(calc(var(--avail) / 2.05),calc((var(--avail) - var(--col)) / 1.695),calc(var(--avail) - 2 * var(--col)));
  /* tallest tablet one screen can carry; .8 is the plate's height over its width, so a width */
  --fith:calc((100svh - var(--hd) - var(--eyeh) - var(--h1pt) - 2.12 * var(--fs) - var(--ixmt) - var(--ixh) - var(--shpt) - var(--shrg) - var(--caph) - var(--shpb) - 6px) / .8);
  /* bound by the window's height, but never under two thirds of what the width would carry:
     past that the first screen runs a little long rather than shrink the work */
  --u:max(min(var(--fitw),var(--fith)),calc(var(--fitw) * .66),250px)}
.hd{display:flex;justify-content:space-between;align-items:center;height:var(--hd);flex:none}
.hd__logo{display:flex;align-items:center;min-height:44px;flex:none}
.hd__logo img{height:22px;width:auto;max-width:none}
.hd nav{display:flex;align-items:center;gap:clamp(18px,2.2vw,32px);font-family:var(--mono);font-size:12.5px;letter-spacing:.06em;text-transform:uppercase}
.hd nav .btn{margin-left:8px}
h1,.h2{font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;line-height:1;letter-spacing:-.04em}
h1{font-size:var(--fs);max-width:15.5em;text-wrap:balance;padding-top:var(--h1pt)}
h1 .w{display:inline-block}
.eye--hero{margin:0 0 clamp(12px,1.8vh,22px);color:var(--ink-2);height:16px}

/* The index. Every name is a live site, and pointing at one puts it on the device it belongs to:
   sites on the tablet, apps on the phone. It hangs off one rule with the ask at the far end of
   the same rule, so nothing on the first screen floats. */
.ix{margin-top:var(--ixmt);border-top:1px solid var(--ink);display:flex;align-items:center;justify-content:space-between;gap:12px 28px;padding-top:14px;flex:none}
.ix__groups{display:flex;flex-wrap:wrap;align-items:center;gap:0 clamp(28px,3.4vw,56px);min-width:0}
.ix__names{display:flex;flex-wrap:wrap;align-items:center;gap:0;min-width:0;color:var(--ink-2);font-size:16px;letter-spacing:-.008em}
.ix__label{display:inline-flex;align-items:center;gap:var(--markgap);color:var(--mute);margin-right:clamp(12px,1.4vw,20px);white-space:nowrap}
.ix__label i{width:var(--mark);height:var(--mark);border-radius:50%;background:var(--accent)}
.ix__hint{flex:none;color:var(--ink-2);white-space:nowrap}
.ix__hint .t{display:none}
@media (hover:none){.ix__hint .m{display:none}.ix__hint .t{display:inline}}
.ix__names li{display:inline-flex;align-items:center}
.ix__names .ix__label + li::before{display:none}
.ix__names li+li::before{content:"";width:3px;height:3px;border-radius:50%;background:#B9B9B4;margin:0 clamp(8px,.95vw,13px)}
.ix__names a{position:relative;display:inline-block;padding:10px 0;transition:color .24s var(--ease-soft)}
.ix__names a::after{content:"";position:absolute;left:0;right:0;bottom:7px;height:1.5px;background:var(--accent);transform:scaleX(0);transform-origin:right;transition:transform .3s var(--ease-out)}
.ix__names a.is-on,.ix__names a:focus-visible{color:var(--ink)}
.ix__names a.is-on::after{transform:scaleX(1);transform-origin:left}
@media (hover:hover) and (pointer:fine){.ix__names a:hover{color:var(--ink)}}

/* The plates. Three objects at their true size against one another (tablet 1 : phone .355 :
   box .695), standing on one ground line; under each a hairline cut to the object's own measure,
   then its name and one sentence. The photographs are multiplied into the page, so NO ancestor
   of one may carry a transform, an opacity, a filter or a z-index: it would isolate the group and
   paint the plate's white ground as a rectangle. Everything that moves here is the img itself. */
.sheet{flex:none;display:grid;grid-template-rows:auto auto;align-content:end;justify-content:space-between;
  grid-template-columns:max(var(--u),var(--col)) max(calc(var(--u) * .355),var(--col)) max(calc(var(--u) * .695),var(--col));
  column-gap:var(--g);row-gap:var(--shrg);padding:var(--shpt) 0 var(--shpb)}
.fig{grid-row:1 / -1;display:grid;grid-template-rows:subgrid;min-width:0}
.fig--tab{--ow:var(--u);--l:.0191;--r:.0191}
.fig--pho{--ow:calc(var(--u) * .355);--l:.0192;--r:.0192}
.fig--box{--ow:calc(var(--u) * .695);--l:.019;--r:.019}
.obj{position:relative;display:block;align-self:end;justify-self:start;width:var(--ow);max-width:100%}
.fig--box .obj{justify-self:end}
/* the phone is narrower than the column its caption needs: it and its caption step in by half the
   difference, so the air either side of the phone is equal (178 against 246 before) */
.fig--pho .obj,.fig--pho .cap{margin-left:max(0px,calc((var(--col) - var(--ow)) / 2))}
.obj img{width:100%;height:auto;transition:transform .35s var(--ease-out)}
.obj .plate{mix-blend-mode:multiply}
/* one ground line: each plate's cast shadow runs to a different depth, so the two shallower ones
   are lifted by the difference and the objects, not their shadows, stand level */
.fig--pho .obj{margin-bottom:calc(var(--u) * .0239)}
.fig--box .obj{margin-bottom:calc(var(--u) * .0283)}
/* A client's screen, cut to the glass and laid over the plate in normal blend. Only ever the
   screen is swapped: two multiplied copies of a whole device darken it while they overlap. */
.obj .scr{position:absolute;opacity:0;transition:opacity .45s var(--ease-soft),transform .35s var(--ease-out);pointer-events:none}
.obj .scr.is-on{opacity:1}
.fig--tab .scr{left:5%;top:6.4846%;width:90%;height:77.7019%}
.fig--pho .scr{left:9.4231%;top:2.761%;width:85.1923%;height:87.0578%}
.cap{align-self:start;justify-self:start;min-height:calc(var(--caph) - var(--u) * .0318);margin-top:calc(var(--u) * -.0318);padding-left:calc(var(--ow) * var(--l));
  --rw:max(calc(var(--ow) * (1 - var(--l) - var(--r))),min(323px,calc(var(--col) - var(--ow) * var(--l))));transition:color .2s var(--ease-soft)}
.fig--box .cap{justify-self:end;padding-left:0;padding-right:calc(var(--ow) * var(--r))}
.rule{display:block;height:1px;background:currentColor;margin-bottom:13px;width:var(--rw)}
.cap__top{display:flex;align-items:center;justify-content:space-between;gap:16px;width:var(--rw);min-height:17px}
.cap__h{display:flex;align-items:center;gap:var(--markgap);font-family:var(--mono);font-size:14px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;line-height:1;white-space:nowrap}
.cap__h i{flex:none;width:var(--mark);height:var(--mark);border-radius:50%;background:var(--accent);transition:transform .22s var(--ease-out)}
.on-ink .cap__h i{background:var(--accent-lit)}
.cap__c{flex:none;color:var(--mute);white-space:nowrap}
.cap__c b{font-weight:400;color:var(--ink)}
.cap__p{margin-top:8px;margin-left:calc(var(--mark) + var(--markgap));max-width:min(calc(var(--rw) - 17px),306px);text-wrap:balance;color:var(--ink-2);font-size:15px;line-height:1.45}
.led{position:absolute;left:82.8%;top:47.4%;width:18%;aspect-ratio:1;margin:-9% 0 0 -9%;border-radius:50%;pointer-events:none;opacity:0;
  background:radial-gradient(circle,rgba(255,226,140,.8) 0,rgba(255,196,80,.3) 30%,rgba(255,196,80,0) 64%);transition:opacity .4s var(--ease-soft)}
@media (hover:hover) and (pointer:fine){
  .fig:hover .obj img{transform:translate3d(0,-6px,0)}
  .fig:hover .cap{color:var(--accent-ink)}
  .fig:hover .cap__h i{transform:scale(1.3)}
  .fig--box:hover .led{opacity:1}
}
@supports not (grid-template-rows:subgrid){
  .sheet{align-items:end}
  .fig{grid-row:auto;display:flex;flex-direction:column;justify-content:flex-end}
  .cap{margin-top:12px}
}

/* ---- the bar that takes over once the first screen has gone ---- */
.bar{position:fixed;left:0;right:0;top:0;z-index:40;height:60px;display:flex;align-items:center;
  background:rgba(235,235,232,.92);-webkit-backdrop-filter:blur(14px) saturate(1.06);backdrop-filter:blur(14px) saturate(1.06);
  border-bottom:1px solid rgba(10,10,11,.09);opacity:0;transform:translate3d(0,-100%,0);visibility:hidden;
  transition:opacity .2s var(--ease-soft),transform .3s var(--ease-out),visibility 0s .3s,background-color .22s var(--ease-soft),border-color .22s var(--ease-soft)}
.bar.is-on{opacity:1;transform:none;visibility:visible;transition-delay:0s}
.bar.is-ink{background:rgba(10,10,11,.92);border-bottom-color:rgba(245,245,241,.12);color:var(--on-ink)}
.bar .wrap{display:flex;align-items:center;justify-content:space-between;gap:20px}
.bar__mark{position:relative;display:block;line-height:0;padding:14px 0;flex:none}
.bar__mark img{height:18px;width:auto;max-width:none;transition:opacity .2s var(--ease-soft)}
.bar__mark .k{position:absolute;left:0;top:14px;opacity:0}
.bar.is-ink .bar__mark .p{opacity:0}
.bar.is-ink .bar__mark .k{opacity:1}
.bar nav{display:flex;align-items:center;gap:clamp(16px,2.2vw,32px);font-family:var(--mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase}
.bar.is-ink .btn{background:var(--on-ink);color:var(--ink)}
.bar.is-ink .btn i{background:var(--accent)}
.bar.is-ink .btn:hover i,.bar.is-ink .btn:focus-visible i,.bar.is-ink .btn:active i{background:var(--ink)}
.bar.is-ink :focus-visible{outline-color:var(--on-ink)}
.bar.is-ink .lnk::after{background:var(--accent-lit)}

/* ================= below the first screen ================= */
.band{position:relative;padding:clamp(84px,12vh,160px) 0}
.on-ink{background:#0A0A0B;color:var(--on-ink);
  background-image:linear-gradient(128.9deg,rgba(250,250,250,.095) 0%,rgba(250,250,250,.02) 40%,rgba(250,250,250,0) 66%)}
.band--paper{background-image:linear-gradient(128.9deg,rgba(255,255,255,.95) 0%,rgba(255,255,255,0) 46%,rgba(122,51,23,.075) 100%)}
.h2{font-size:clamp(34px,4.7vw,76px);max-width:14em;text-wrap:balance}
.eye{display:flex;align-items:center;gap:var(--markgap);margin-bottom:clamp(18px,2.4vh,28px);color:var(--mute)}
.on-ink .eye{color:var(--on-ink-3)}
.eye i{width:var(--mark);height:var(--mark);border-radius:50%;background:var(--accent)}
.on-ink .eye i{background:var(--accent-lit)}
.say{margin-top:22px;max-width:52ch;text-wrap:pretty;color:var(--ink-2);font-size:clamp(16px,1.2vw,18px);line-height:1.55}
.on-ink .say{color:var(--on-ink-2)}

/* ---- work: a plate the width of the frame. The desktop site and the phone site stand on one
   line at one height, and each travels inside its window as the page moves, so a visitor is
   shown the whole site for the price of scrolling past it. Both windows are one link. */
.cases{margin-top:clamp(52px,8vh,104px);display:grid;gap:clamp(72px,11vh,148px)}
.case__wins{display:grid;grid-template-columns:3.4617fr 1fr;gap:clamp(12px,2.6vw,48px);align-items:end}
.case:nth-child(even) .case__wins{grid-template-columns:1fr 3.4617fr}
.case:nth-child(even) .win--m{order:-1}
.win{position:relative;display:block;overflow:hidden;border-radius:clamp(6px,.8vw,12px);background:#141416;
  box-shadow:0 0 0 1px rgba(245,245,241,.13),0 40px 80px -40px rgba(0,0,0,.9)}
.win--d{aspect-ratio:1440/900}
.win--m{aspect-ratio:390/844;border-radius:clamp(8px,1.5vw,24px)}
.win img{position:absolute;left:0;top:0;width:100%;height:auto;max-width:none;will-change:transform}
.win::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:inset 0 0 0 1px rgba(245,245,241,.1);transition:box-shadow .3s var(--ease-soft)}
.case__wins:focus-visible{outline:2px solid var(--accent-lit);outline-offset:8px;border-radius:12px}
.case__cap{margin-top:clamp(18px,2.6vh,28px);border-top:1px solid var(--rule-ink);padding-top:16px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 40px;align-items:start;transition:border-color .3s var(--ease-soft)}
.case__cap .cap__h{font-size:15px;padding:8px 0}
.case__p{grid-column:1;max-width:56ch;color:var(--on-ink-2);font-size:clamp(15px,1.15vw,17px);line-height:1.5;text-wrap:pretty}
.case__go{grid-column:2;grid-row:1;justify-self:end;color:var(--on-ink);padding:10px 0}
.case__tags{grid-column:2;grid-row:2;justify-self:end;display:flex;flex-wrap:wrap;justify-content:flex-end;gap:4px 20px;max-width:44ch;color:var(--on-ink-3)}
@media (hover:hover) and (pointer:fine){
  .case:hover .case__cap{border-color:var(--accent-lit)}
  .case:hover .case__go::after{transform:scaleX(1);transform-origin:left}
  .case:hover .cap__h i{transform:scale(1.3)}
  .case:hover .win::after{box-shadow:inset 0 0 0 1px rgba(245,245,241,.26)}
}

/* The one measured result. It is a traffic figure, it belongs to the three sites above it and to
   nothing else on the page, and it carries its sample and its window in the same sentence. */
.note{margin-top:clamp(72px,11vh,140px);display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(28px,5vw,96px);align-items:end}
.note__q{display:inline-flex;flex-direction:column}
.note__fig{font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:clamp(84px,12.5vw,208px);line-height:.82;letter-spacing:-.05em;color:var(--accent-lit);font-variant-numeric:tabular-nums}
.note__rule{height:2px;margin-top:clamp(16px,1.8vw,28px);background:var(--accent-lit);transform-origin:left}
.note__p{font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:clamp(22px,2.95vw,48px);line-height:1.12;letter-spacing:-.032em;text-wrap:balance;padding-bottom:clamp(0px,.4vw,6px)}

/* The trust bar: every client's own wordmark, photographed from its own header and keyed to a
   single colour mask (tools/preview/logos.mjs, tools/logo-masks.py), so seven brands share one
   tone. Nothing here is a link: the three sites above do the selling. Three identical sets and a
   travel of exactly one set, so the loop has no seam and a wide window never shows a gap. */
.trust{margin-top:clamp(72px,11vh,140px);border-top:1px solid var(--rule-ink);padding-top:clamp(22px,3vh,34px);display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:clamp(24px,4vw,64px)}
.trust__k{color:var(--on-ink-3);white-space:nowrap}
.trust__view{overflow:hidden;-webkit-mask-image:linear-gradient(to right,transparent 0,#000 9%,#000 91%,transparent 100%);mask-image:linear-gradient(to right,transparent 0,#000 9%,#000 91%,transparent 100%)}
.trust__track{display:flex;width:max-content;animation:marquee 48s linear -12s infinite}
.trust__set{display:flex;align-items:center;flex:none;gap:clamp(44px,5.2vw,88px);padding-right:clamp(44px,5.2vw,88px);height:44px}
.trust__set li{display:flex;align-items:center}
.tm{display:block;height:calc(var(--h) * 1px);width:calc(var(--h) * var(--r) * 1px);background:var(--on-ink);opacity:.62;
  /* the image itself is set inline on each mark: a url() inside a custom property resolves against
     this stylesheet, not the page, and 404s */
  -webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
@keyframes marquee{to{transform:translate3d(-33.3333%,0,0)}}

/* ---- the offer ----
   One band in the colour of the box, with the lit face running across it: the page goes Paper,
   Ink, orange, Ink. Everything the section has to say is three figures and three steps, set side
   by side and fitted to one screen; what is inside each service is a sentence, not a list.
   Nothing is ruled. On this ground every piece of text is full Ink: Ink on the orange is 4.8:1,
   and any grey of it would fall under AA, so hierarchy is carried by size and weight alone.
   The lit face only ever LIGHTENS the ground, for the same reason. */
.band--signal{padding:clamp(72px,10vh,132px) 0;background:#D05828;color:var(--ink);
  background-image:linear-gradient(128.9deg,rgba(255,255,255,.24) 0%,rgba(255,255,255,.06) 38%,rgba(255,255,255,0) 62%)}
.band--signal .eye{color:var(--ink)}
.band--signal .eye i,.band--signal .cap__h i{background:var(--ink)}
.band--signal .stop{background:var(--on-ink)}
.band--signal ::selection{background:rgba(10,10,11,.85);color:var(--on-ink)}
/* THE LINE. The section is one drawing: five numbered discs joined by a line, from the first email
   to the month after launch, and every fact hangs from the disc where it becomes true: the button
   from the first, one day from the second, five days from the third, the two plans from the last
   two. The line runs DISC TO DISC and ends on the last one. (It once ran on out of the right of
   the window, to say that hosting does not end; it also meant the drawing began on a stop and
   ended on an edge, and its weight slid off to the right.) Each stop draws its own segment to
   the next, so the line builds stop by stop and needs no measuring.
   Desktop: five equal columns, rows subgrid so titles, figures and sentences each share a line.
   Under 1180px the same line stands upright down the left edge. */
.band--signal .h2{max-width:13em}
/* On a desktop the headline is one line the width of the frame, running parallel to the line under
   it: it measures 16.6em wide, so 5.45vw fills the 92.8vw frame, capped where the frame is. */
@media (min-width:1181px){.band--signal .h2{max-width:none;white-space:nowrap;font-size:min(5.45vw,93px)}}
.tl{--tg:clamp(20px,2.6vw,48px);--d:44px;position:relative;margin-top:clamp(44px,7vh,92px);display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  grid-template-rows:auto auto auto;column-gap:var(--tg);padding-top:calc(var(--d) + clamp(18px,2.6vh,28px))}
.tl__stop{position:relative;display:grid;grid-row:1 / span 3;grid-template-rows:subgrid;grid-template-columns:minmax(0,1fr);align-items:start}
.tl__disc{position:absolute;z-index:1;left:0;top:calc(-1 * (var(--d) + clamp(18px,2.6vh,28px)));width:var(--d);height:var(--d);border-radius:50%;background:var(--ink);color:var(--on-ink);
  display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;letter-spacing:.04em}
/* The two plans are Paper discs with Ink numerals: the first three stops are a sequence you go
   through, these two are a pair you choose between, and the colour says so before the words do.
   Paper is already this band's second colour (the headline's full stop, the button's flood). */
.tl__stop:nth-child(n+4) .tl__disc{background:var(--on-ink);color:var(--ink)}
/* "or" is TYPE, set on the figures' own baseline like "/mo", so the row reads as a phrase: $50/mo or
   $150/mo. It was a 28px disc, which read as a stray speck beside 108px figures and gave discs a
   second meaning; now a disc is only ever a stop on the line. On a desktop it is centred in the
   space between the two prices (the $50 figure is let out through the column gap so that space can
   be centred in). Where the line is upright it is a second element, a child of the stop and not of
   the figure: the figure carries a transform while it arrives, which would make it the containing
   block and drag an absolutely placed word with it. */
.tl__fig .tl__or,.tl__or{font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:clamp(19px,1.75vw,28px);letter-spacing:-.03em;line-height:1;text-transform:none;color:var(--ink)}
.tl__or--line{display:none;position:absolute;z-index:1}
.tl__fig .tl__or--fig{margin:0 auto .02em}
.tl__stop:nth-child(4) .tl__fig{margin-right:calc(-1 * var(--tg))}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* this stop's segment: from the centre of its disc to the centre of the next one */
.tl__stop::after{content:"";position:absolute;left:calc(var(--d) / 2);top:calc(-1 * (var(--d) / 2 + clamp(18px,2.6vh,28px)) - 1px);height:2px;width:calc(100% + var(--tg));background:var(--ink);transform-origin:left}
.tl__stop:last-child::after{display:none}
/* solid is "then", dashed is "or": the two plans are alternatives, not a fourth and a fifth step */
.tl__stop:nth-child(4)::after{background:repeating-linear-gradient(to right,var(--ink) 0 7px,transparent 7px 14px)}
.tl__h{grid-row:1;font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:clamp(20px,1.75vw,28px);line-height:1.1;letter-spacing:-.03em;white-space:nowrap}
.tl__fig{grid-row:2;margin-top:clamp(20px,3vh,34px);font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:min(6.3vw,108px);line-height:.8;letter-spacing:-.06em;font-variant-numeric:tabular-nums;white-space:nowrap;
  display:flex;align-items:flex-end;min-height:.8em}
.tl__fig span{font-family:"Mona Sans",system-ui,sans-serif;font-size:clamp(13px,1.05vw,17px);font-weight:500;letter-spacing:0;line-height:1.15;margin:0 0 .08em .4em;white-space:nowrap}
.tl__p{grid-row:3;margin-top:clamp(16px,2vh,24px);max-width:24em;font-size:clamp(15px,1.08vw,17.5px);line-height:1.45;text-wrap:balance}
.tl__p b{font-weight:600}
@supports not (grid-template-rows:subgrid){.tl__stop{display:block;grid-row:auto}}
/* each disc lands, its segment runs to the next, and what hangs from it follows */
html.motion .tl[data-reveal]{opacity:1;transform:none}
html.motion .tl .tl__disc{opacity:0;transform:scale(.4);transition:opacity .35s var(--ease-soft),transform .7s var(--ease-out);transition-delay:calc(.05s + var(--n) * .3s)}
html.motion .tl.in .tl__disc{opacity:1;transform:none}
html.motion .tl .tl__stop::after{transform:scaleX(0);transition:transform .42s cubic-bezier(.45,0,.4,1);transition-delay:calc(.2s + var(--n) * .3s)}
html.motion .tl.in .tl__stop::after{transform:none}
html.motion .tl .tl__stop:nth-child(4)::after{transform:none;clip-path:inset(0 100% 0 0);transition:clip-path .42s cubic-bezier(.45,0,.4,1);transition-delay:calc(.2s + var(--n) * .3s)}
html.motion .tl.in .tl__stop:nth-child(4)::after{clip-path:inset(0)}
html.motion .tl .tl__or{opacity:0;transition:opacity .6s var(--ease-soft);transition-delay:1.45s}
html.motion .tl.in .tl__or{opacity:1}
html.motion .tl .tl__stop > :not(.tl__disc):not(.tl__or){opacity:0;transform:translate3d(0,16px,0);transition:opacity .8s var(--ease-soft),transform 1s var(--ease-out);transition-delay:calc(.16s + var(--n) * .3s)}
html.motion .tl.in .tl__stop > :not(.tl__disc):not(.tl__or){opacity:1;transform:none}

/* ---- the close ---- */
/* The macro and its two scrims share ONE box, sized from the picture (2400x1340), and both scrims
   reach solid Ink on the edges where that box ends inside the band: its left and its bottom. So
   the picture has no edge anywhere, at any window size. Sized as cover, the scrims ended where
   the BAND ended and the picture stopped part way down it against a visible line. */
.close{padding-bottom:0;overflow:hidden;background-image:none;
  /* the box's left edge sits .8 of the picture's height in from the right: held clear of the 560px form */
  --ih:clamp(440px,calc((100vw - var(--pad) - 620px) / .8),980px);
  /* the picture is centred on the headline and form, which run about 1180px from the band's top */
  --iy:max(56px,calc((1180px - var(--ih)) / 2))}
.close::before{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:
    linear-gradient(to bottom,#0A0A0B 0%,rgba(10,10,11,.72) 7%,rgba(10,10,11,.2) 17%,rgba(10,10,11,0) 26%,rgba(10,10,11,.12) 46%,rgba(10,10,11,.82) 76%,#0A0A0B 94%),
    linear-gradient(to right,#0A0A0B 0%,#0A0A0B 8%,rgba(10,10,11,.9) 30%,rgba(10,10,11,.5) 52%,rgba(10,10,11,.12) 78%,rgba(10,10,11,0) 100%),
    url(../img/close-dial.webp);
  /* set down from the band above and faded to Ink along its top edge as well: in the photograph the
     box runs out of the top of the frame, so flush to the top it butted into the section before it */
  background-size:calc(var(--ih) * 1.791) var(--ih);background-position:right var(--iy);background-repeat:no-repeat}
/* the macro is a background, which no browser lazy loads: it waits until the band is near */
html.defer-bg .close:not(.is-near)::before{background-image:none}
.close .wrap{position:relative}
.close .h2{font-size:clamp(44px,7.6vw,128px);max-width:9em}
.ask{margin-top:clamp(40px,6vh,72px);max-width:min(560px,54vw)}
.form{display:grid;gap:22px}
.field label{display:block;margin-bottom:8px;color:var(--on-ink-2)}
.field input,.field textarea{display:block;width:100%;min-height:48px;padding:12px 0;border:0;border-bottom:1px solid rgba(245,245,241,.34);border-radius:0;background:transparent;color:var(--on-ink);
  font:400 17px/1.4 "Mona Sans",system-ui,sans-serif;transition:border-color .2s var(--ease-soft)}
.field textarea{resize:none;max-height:240px;overflow:auto}
.field input:hover,.field textarea:hover{border-bottom-color:rgba(245,245,241,.6)}
.field input:focus-visible,.field textarea:focus-visible{outline:0;border-bottom-color:var(--accent-lit);box-shadow:0 1px 0 var(--accent-lit)}
.field__bad{margin-top:8px;font-size:14px;color:#FFB08A}
.field.is-bad input,.field.is-bad textarea{border-bottom-color:#FFB08A}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form__go{display:flex;flex-wrap:wrap;align-items:center;gap:14px 24px;margin-top:6px}
.form__note{color:var(--on-ink-3);font-size:14px}
.done h3{font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:clamp(30px,3vw,44px);line-height:1.02;letter-spacing:-.035em}
.done p{margin-top:14px;max-width:46ch;color:var(--on-ink-2)}
.done__acts{margin-top:26px;display:flex;flex-wrap:wrap;align-items:center;gap:14px 24px}
.linkbtn{background:none;border:0;color:var(--on-ink);font:inherit;cursor:pointer;min-height:44px}
.direct{margin-top:clamp(44px,6vh,64px);border-top:1px solid var(--rule-ink);padding-top:18px}
.direct__k{color:var(--on-ink-3)}
.direct__mail{display:inline-block;margin-top:8px;font-family:var(--disp);font-variation-settings:"opsz" 96;font-weight:500;font-size:clamp(24px,2.6vw,42px);letter-spacing:-.035em;line-height:1.1;padding:6px 0}
.direct__p{margin-top:10px;max-width:36ch;color:var(--on-ink-2);font-size:15px}
.foot{margin-top:clamp(88px,13vh,168px);border-top:1px solid var(--rule-ink);padding:26px 0 clamp(28px,4vh,44px);display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:32px clamp(48px,7vw,128px)}
.foot__mark img{height:20px;width:auto}
.foot__say{margin-top:16px;max-width:34ch;color:var(--on-ink-2);font-size:15px}
.foot__k{color:var(--on-ink-3);margin-bottom:8px}
.foot__col a{display:block;width:fit-content;padding:7px 0;color:var(--on-ink);font-size:15px}
.foot__legal{grid-column:1 / -1;color:var(--on-ink-3);padding-top:8px}

/* ================= motion =================
   html.motion is set in the head before first paint and taken away again after three seconds if
   the script never arrives, so nothing can be left invisible. The first screen runs on keyframes
   and not on transitions: on a warm load a transition has no first frame to leave from and never
   fires. Below the first screen a class is added as a block comes into range, restated on every
   scroll so a flick or a scrollbar drag cannot strand one. */
@keyframes rise{from{opacity:0;transform:translate3d(0,var(--ty,22px),0)}to{opacity:1;transform:none}}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes draw{from{transform:scaleX(.02)}to{transform:none}}
html.motion .hd{animation:fade .9s var(--ease-soft) both}
html.motion h1 .w{animation:rise 1.1s var(--ease-out) calc(80ms + var(--i,0) * 38ms) both;--ty:.42em}
html.motion h1:not(.is-split){animation:rise 1.1s var(--ease-out) 80ms both}
html.motion h1 .stop{animation:fade .5s var(--ease-soft) 760ms both}
html.motion .eye--hero{animation:fade .9s var(--ease-soft) 60ms backwards}
html.motion .ix{animation:fade .9s var(--ease-soft) 420ms backwards}
html.motion .sheet .plate{animation:rise 1.25s var(--ease-out) calc(480ms + var(--dl,0ms)) backwards;--ty:26px}
html.motion .sheet .cap{animation:rise 1s var(--ease-out) calc(760ms + var(--dl,0ms)) backwards;--ty:10px}
html.motion .sheet .rule{animation:draw 1.1s var(--ease-out) calc(760ms + var(--dl,0ms)) backwards;transform-origin:left}
html.motion [data-reveal]{opacity:0;transform:translate3d(0,28px,0);transition:opacity .9s var(--ease-soft),transform 1.1s var(--ease-out);transition-delay:calc(var(--i,0) * 70ms)}
html.motion [data-reveal].in{opacity:1;transform:none}
html.motion .note__rule{transform:scaleX(.02);transition:transform 1.4s var(--ease-out) .25s}
html.motion .note.in .note__rule{transform:none}
/* reduced motion: things still arrive, they just do not travel */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  html.motion h1 .w,html.motion h1:not(.is-split),html.motion .sheet .plate,html.motion .sheet .cap{animation-name:fade;animation-duration:.7s}
  html.motion .sheet .rule{animation:none}
  html.motion [data-reveal]{transform:none;transition:opacity .7s var(--ease-soft)}
  html.motion .note__rule{transform:none;transition:none}
  html.motion .tl .tl__stop::after,html.motion .tl .tl__stop:nth-child(4)::after{transform:none;clip-path:none;transition:none}
  html.motion .tl .tl__disc,html.motion .tl .tl__or{transform:none}
  html.motion .tl .tl__stop > :not(.tl__disc):not(.tl__or){transform:none}
  .btn::before,.btn:hover::before,.btn:focus-visible::before,.btn:active::before{transition:none}
  .obj img{transition:opacity .45s var(--ease-soft)}
  .fig:hover .obj img{transform:none}
  /* the bar stops, and wraps into a still row so every mark can still be seen */
  .trust__track{animation:none;width:auto}
  .trust__set{flex-wrap:wrap;row-gap:22px;height:auto}
  .trust__set[aria-hidden]{display:none}
  .trust__view{-webkit-mask-image:none;mask-image:none}
  .lnk::after,.ix__names a::after{transition:none}
  .bar{transition:opacity .2s var(--ease-soft),visibility 0s;transform:none}
}

/* ================= narrower windows ================= */
/* from here up every caption sets in two lines, so the row gets the third line's height back */
@media (min-width:1280px){.hero__in{--caph:86px}}
@media (max-width:1180px){
  /* the same line, upright: the discs run down the left edge and each stop hangs to their right */
  .tl{display:block;--M:clamp(40px,6vh,60px);--ind:calc(var(--d) + clamp(16px,3vw,28px));padding:0 0 0 var(--ind);max-width:760px}
  .tl__stop{display:block}
  .tl__stop + .tl__stop{margin-top:var(--M)}
  .tl__disc{left:calc(-1 * var(--ind));top:-10px}
  .tl__or--fig,.tl__fig .tl__or--fig{display:none}
  .tl__stop:nth-child(4) .tl__fig{margin-right:0}
  .tl__or--line{display:block;left:0;top:calc(100% + var(--M) / 2 - .62em)}
  .tl__stop:nth-child(4)::after{background:repeating-linear-gradient(to bottom,var(--ink) 0 7px,transparent 7px 14px)}
  html.motion .tl .tl__stop:nth-child(4)::after{clip-path:inset(0 0 100% 0)}
  .tl__stop:nth-child(4) + .tl__stop{margin-top:calc(var(--M) + 22px)}
  .tl__stop:nth-child(4){--M:calc(clamp(40px,6vh,60px) + 22px)}
  .tl__stop::after{left:calc(-1 * var(--ind) + var(--d) / 2 - 1px);top:calc(var(--d) / 2 - 10px);width:2px;height:calc(100% + var(--M));transform-origin:top}
  html.motion .tl .tl__stop::after{transform:scaleY(0)}
  .tl__fig{font-size:clamp(60px,15vw,104px);margin-top:18px}
  .tl__p{margin-top:12px;max-width:34em}
  .ix__hint{display:none}
}
/* Between a phone and a full desktop the upright line must still fill the frame: each stop sets its
   title, its figure and its sentence in three columns beside the line, so the right half of the
   window is not left empty (it was, at 1024). */
@media (min-width:701px) and (max-width:1180px){
  .tl{max-width:none}
  .tl__stop{--cg:clamp(20px,3vw,40px);display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1fr) minmax(0,1.5fr);column-gap:var(--cg);align-items:end}
  .tl__h{grid-column:1;grid-row:1;align-self:center}
  .tl__fig{grid-column:2;grid-row:1;margin:0;font-size:clamp(60px,9vw,96px)}
  .tl__p{grid-column:3;grid-row:1;margin:0;max-width:30em}
  .tl__disc{top:50%;margin-top:calc(var(--d) / -2)}
  /* the figure column starts .9 of 3.4 shares in, plus one gap; the disc sits half way down to the next figure */
  .tl__or--line{left:calc((100% - 2 * var(--cg)) * .2647 + var(--cg) + 4px)}
  .tl__stop::after{top:50%}
}
@media (max-width:1180px){
}
/* the first screen stacks on a phone, and on any window taller than it is wide: a row of three
   objects is bound by width there and would leave half a screen of nothing under it */
@media (max-width:860px),(max-width:1180px) and (max-aspect-ratio:1/1){
  .hero__in{min-height:0;justify-content:flex-start;--hd:72px;--fs:clamp(38px,10.6vw,84px);--u:calc((100vw - 2 * var(--pad) - 14px) / 1.355)}
  .ix{flex-direction:column;align-items:flex-start;padding-top:12px}
  .ix__groups{display:block;width:100%}
  .ix__label{width:100%;margin:0}
  .ix__names{gap:0 16px}
  .ix__names + .ix__names{margin-top:6px}
  .fig--pho .obj,.fig--pho .cap{margin-left:0}
  .ix__names li+li::before{display:none}
  .ix__names a{padding:12px 0}
  .ix__names a::after{bottom:9px}
  /* On a phone the tablet and the phone stand side by side on one ground line, which their
     proportions happen to allow (2.82 : 1 wide comes out one height), and the box stands beside
     its own caption in the phone's column. The figures dissolve so that objects and captions can
     be placed on the sheet's own grid. */
  .sheet{grid-template-columns:minmax(0,2.82fr) minmax(0,1fr);grid-template-rows:none;column-gap:14px;row-gap:0;align-items:end;justify-content:stretch;
    padding:clamp(28px,5vh,44px) 0 clamp(44px,7vh,64px);grid-template-areas:"tab pho" "ct ct" "cp cp" "cb box"}
  .fig{display:contents}
  .fig .obj{width:100%;margin:0}
  .fig--tab .obj{grid-area:tab}
  .fig--pho .obj{grid-area:pho;margin-bottom:calc((100vw - 2 * var(--pad)) * .017)}
  .fig--box .obj{grid-area:box;align-self:center;margin-top:26px}
  .cap,.fig--box .cap{--rw:100%;width:100%;padding:0;margin-top:26px;justify-self:stretch;align-self:start}
  .fig--tab .cap{grid-area:ct;margin-top:16px}
  .fig--pho .cap{grid-area:cp}
  .fig--box .cap{grid-area:cb}
  .cap{min-height:0}
  .cap__p{max-width:34ch}
  .ix__hint{display:block;margin-top:-4px}
}
@media (max-width:860px){
  html{scroll-padding-top:64px}
  .hd nav .lnk{display:none}
  .bar nav .lnk{display:none}
  .hd__logo img{height:19px}
  .note{grid-template-columns:minmax(0,1fr);align-items:start}
  .trust{grid-template-columns:minmax(0,1fr);gap:18px}
  .tm{height:calc(var(--h) * .74px);width:calc(var(--h) * var(--r) * .74px)}
  .trust__set{gap:40px;padding-right:40px;height:36px}
  .trust__track{animation-duration:36s}
    /* the picture is a band across the top of the close and the type starts where it has gone to Ink */
  .close{--ih:clamp(240px,64vw,460px);--iy:20px;padding-top:calc(var(--ih) * .8 + 20px)}
  .ask{max-width:none}
  .close::before{background-image:linear-gradient(to bottom,#0A0A0B 0%,rgba(10,10,11,.5) 8%,rgba(10,10,11,.1) 20%,rgba(10,10,11,.2) 50%,#0A0A0B 94%),linear-gradient(to right,#0A0A0B 0%,rgba(10,10,11,.55) 34%,rgba(10,10,11,0) 100%),url(../img/close-dial.webp)}
  .foot{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot__id{grid-column:1 / -1}
  .foot__col a{padding:12px 0}
}
@media (max-width:600px){
  /* On a phone the two windows overlap instead of standing side by side, which would leave the
     phone window 70px wide: the desktop site runs the full measure and the phone site stands in
     front of its lower right corner, over the caption's rule, with the name and the link beside it. */
  .cases{--W:calc(100vw - 2 * var(--pad))}
  .case__wins,.case:nth-child(even) .case__wins{display:block;position:relative}
  .win--m,.case:nth-child(even) .win--m{position:absolute;right:4%;top:calc(var(--W) * .2375);width:30%;z-index:1;box-shadow:0 0 0 1px rgba(245,245,241,.2),0 24px 50px -16px #000}
  .case__cap{grid-template-columns:minmax(0,1fr);margin-top:18px}
  .case__cap .cap__h,.case__go{max-width:60%}
  .case__go,.case__tags{grid-column:1;grid-row:auto;justify-self:start;justify-content:flex-start}
  .case__go{padding:14px 0}
  .direct__mail{padding:10px 0}
  .foot__mark{display:flex;align-items:center;min-height:44px}
  .foot__col a{min-width:44px}
  .case__p{margin-top:max(14px,calc(var(--W) * .2815 - 96px))}
  .case__tags{margin-top:12px}
}
@media (max-width:520px){

  .btn--sm{--px:14px;font-size:11.5px;letter-spacing:.06em}
  .bar__mark img{height:16px}
  .hd__logo img{height:17px}
}
@media (max-width:380px){
  .btn__x{display:none}
}
