/* The Cloud face — DIRECTION A ("Pulse Rail"), the operator's pick of 2026-09-07.
 *
 * Lifted from the approved boards themselves (design-cloud/r2/A-landing.html, A-apps.html,
 * A-pay.html) rather than re-typed from the renders: the boards ARE the specification, and a
 * hand-copied palette is how a design drifts on its first day.
 *
 * SCOPE. This sheet dresses the CLOUD face only — the pages served by views/console/layout.php.
 * The SaaS Kit is also a product in its own right and keeps its crimson identity in style.css;
 * the kit's admin console (admin_layout.php) is untouched. Two faces, one codebase, one sheet
 * each.
 *
 * Palette: paper #fbfbfd · ink #0b0f1a · indigo #4f46e5 → cyan #06b6d4 · live #10b981.
 * Type: Plus Jakarta Sans 800 (display) · Inter (text) · JetBrains Mono (eyebrows, addresses).
 * Signature: the provisioning rail — PAY → RESERVE → BUILD → LIVE on a dashed wire.
 * prefers-reduced-motion stops every animation; nothing here depends on movement to be legible.
 *
 * Fonts are served from this plane (assets/fonts/, latin subsets, OFL licences beside them), not
 * from Google's font service, which was handed every visitor's IP address as a third party the
 * legal page did not name (SPRINT-26H, 2026-09-25). The store already self-hosts the same way.
 */
@font-face{font-family:'Inter';font-style:normal;font-weight:100 900;font-display:swap;src:url('fonts/inter-var-latin.woff2') format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:700 800;font-display:swap;src:url('fonts/plus-jakarta-sans-latin.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 700;font-display:swap;src:url('fonts/jetbrains-mono-latin.woff2') format('woff2')}
:root{--bg:#fbfbfd;--card:#ffffff;--field:#ffffff;--ink:#0b0f1a;--dim:#4b5563;--faint:#636b79;--line:#e6e8ef;--line2:#d5d9e3;--accent:#4f46e5;--accent2:#06b6d4;--accentsoft:#eef2ff;--accentink:#fff;--soft:#f1f3f7;--live:#10b981;--liveglow:0 8px 30px -14px rgba(79,70,229,.45);--btnbg:linear-gradient(120deg,#4f46e5,#06b6d4);--btnink:#fff;--barbg:rgba(251,251,253,.78);--footbg:#f4f5fa;--display:"Plus Jakarta Sans",system-ui,sans-serif;--sans:Inter,system-ui,sans-serif;--mono:"JetBrains Mono",ui-monospace,monospace;--r:12px;--rl:16px;--hw:800}
*{box-sizing:border-box}
html,body{margin:0;overflow-x:hidden;max-width:100%}
/* Short pages (checkout, account, the walls) ended with a band of page background below the
   footer, which reads as an unfinished edge. The footer sits at the bottom of the viewport
   when there is not enough content to push it there, and stays in flow when there is. */
body{font-family:var(--sans);color:var(--ink);background:var(--bg);font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased;min-height:100vh;display:flex;flex-direction:column}
body > main{flex:1 0 auto;width:100%}  /* .wrap's auto side margins suppress flex stretch, so
                                          main shrank to its content once body became a column */
a{color:inherit}
.wrap{max-width:1180px;margin:0 auto;padding:0 28px}
@media(max-width:640px){.wrap{padding:0 16px}}
.bar{position:sticky;top:0;z-index:30;display:flex;justify-content:space-between;align-items:center;gap:14px;padding:14px 28px;background:var(--barbg);backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.bar .brand{font-family:var(--display);font-weight:800;font-size:17px;text-decoration:none;letter-spacing:-.01em;display:flex;align-items:center;gap:8px;white-space:nowrap}
.bar .brand b{color:var(--accent)}
.bar nav{display:flex;gap:16px;align-items:center;font-size:13.5px;flex-wrap:nowrap}
/* G2(d), 2026-09-07: :not(.btn) is load-bearing. `.bar nav a` is (0,1,2) and `.btn` is (0,1,0),
   so the nav's --dim WON over --btnink and the header's Start pill rendered #4b5563 grey on the
   indigo->cyan gradient: measured 1.07:1 against the indigo end, i.e. effectively invisible, on the
   plane's primary call to action. The approved board A-landing.html carries the same collision --
   this is not drift from the spec, it is the spec's own bug -- and the same call the filter-chip
   fix made applies: a static mockup may ship an inconsistency, a page a customer touches may not.
   The nav idiom for exempting the pill already exists one rule below (:not(.shop):not(.cta)). */
.bar nav a:not(.btn){text-decoration:none;color:var(--dim);white-space:nowrap}
.bar nav a.on{color:var(--ink);font-weight:600}
/* Phones keep the way OUT (to the store) and the way ON (Start). The current-page link was
   what survived before, which spent the only slot on a link to the page you are already
   reading; the brand is already that link. */
@media(max-width:900px){.bar nav a:not(.shop):not(.cta){display:none}.bar{padding:12px 16px}}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:13px 20px;border-radius:var(--r);font-weight:650;font-size:14.5px;text-decoration:none;border:0;cursor:pointer;color:var(--btnink);background:var(--btnbg);position:relative;overflow:hidden;transition:transform .18s ease,box-shadow .18s ease}
.btn:hover{transform:translateY(-2px)}
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line2)}
.btn.lg{padding:15px 24px;font-size:15.5px}
.btn.block{width:100%}
.btn.sm{padding:9px 14px;font-size:13px}
.eyebrow{font-family:var(--mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:14px}
h1{font-family:var(--display);font-weight:var(--hw);font-size:clamp(2.2rem,5.4vw,4rem);line-height:1;letter-spacing:-.025em;margin:0 0 18px;max-width:19ch}
h1 em{font-style:normal;color:var(--accent)}
h2{font-family:var(--display);font-weight:var(--hw);font-size:clamp(1.6rem,3vw,2.3rem);letter-spacing:-.02em;margin:0 0 10px;line-height:1.1}
.lead{font-size:17px;color:var(--dim);max-width:54ch;margin:0 0 26px}
.sub{color:var(--dim);max-width:62ch;margin:0 0 20px}
.fine{color:var(--faint);font-size:12.5px;max-width:72ch;line-height:1.55}
.sect{padding:56px 0 8px}
@media(max-width:640px){.sect{padding:40px 0 4px}}
.hero{padding:64px 0 24px;position:relative}
.hero .grid2{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:36px;align-items:center}
.hero .grid2>div{min-width:0}
@media(max-width:900px){.hero .grid2{grid-template-columns:minmax(0,1fr)}}
.cta-row{display:flex;gap:10px;flex-wrap:wrap}
.feat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media(max-width:980px){.feat-grid{grid-template-columns:1fr 1fr}}
@media(max-width:640px){.feat-grid{grid-template-columns:1fr}}
.feat{background:var(--card);border:1px solid var(--line);border-radius:var(--rl);padding:18px}
.feat b{display:block;margin-bottom:6px;font-family:var(--display);font-size:15.5px}
.feat p{margin:0;color:var(--dim);font-size:13.5px}
.plan-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media(max-width:980px){.plan-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.plan-grid{grid-template-columns:1fr}}
.plan{display:flex;flex-direction:column;gap:9px;background:var(--card);border:1px solid var(--line);border-radius:var(--rl);padding:18px;min-height:300px}
.plan .n{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim)}
.plan .p{font-family:var(--display);font-weight:800;font-size:30px;letter-spacing:-.03em;line-height:1}
.plan .p span{font-family:var(--sans);font-size:13px;color:var(--dim);font-weight:500;letter-spacing:0;margin-left:2px}
.plan ul{margin:0;padding:0;list-style:none;font-size:13px;color:var(--dim);display:grid;gap:4px}
.plan li{padding-left:18px;position:relative}
.plan li::before{content:"";position:absolute;left:0;top:7px;width:9px;height:9px;border-radius:99px;background:var(--accent);opacity:.85}
.plan .btn{margin-top:auto}
.form{display:grid;gap:12px}
.row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:640px){.row{grid-template-columns:1fr}}
label{display:block;font-size:12px;font-weight:600;margin-bottom:5px;color:var(--dim);letter-spacing:.02em}
.in{border:1px solid var(--line2);border-radius:10px;padding:11px 12px;background:var(--field);font-size:14.5px;color:var(--ink);width:100%;font-family:var(--sans)}
.subrow{display:flex;gap:8px;align-items:center}
.subrow .dom{font-family:var(--mono);font-size:13px;color:var(--accent)}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--rl);padding:22px}
/* apps grid — equal heights, CTA pinned to the bottom, two states at a glance */
.filters{display:flex;gap:8px;flex-wrap:wrap;margin:6px 0 18px}
button.chip{background:none;cursor:pointer}
.chip{font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;padding:7px 12px;border-radius:99px;border:1px solid var(--line2);color:var(--dim)}
.chip.on{background:var(--accent);color:var(--accentink);border-color:transparent}
.apps{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;grid-auto-rows:1fr}
@media(max-width:980px){.apps{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.apps{grid-template-columns:1fr;grid-auto-rows:auto}}
.app[hidden]{display:none}  /* .app sets display:flex, which outranks the UA [hidden] rule */
.app{display:flex;flex-direction:column;gap:8px;min-height:232px;padding:16px;border-radius:var(--rl);background:var(--card);border:1px solid var(--line)}
.app .nm{font-family:var(--display);font-size:16px;font-weight:700}
.app p{margin:0;font-size:13px;color:var(--dim);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.app .btn{margin-top:auto}
.app.live{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent) inset,var(--liveglow)}
.app.soon{border-style:dashed;background:transparent}
.app.soon .nm,.app.soon p{opacity:.62}
/* OYA, per the 2026-09-07 02:20 ruling: a normal card, slightly highlighted. ONE treatment —
   the dashed border takes the accent colour. Deliberately NOT the .live treatment (solid border
   + inset ring + glow): OYA is not live on Cloud, and a highlight that reads as 'live' would be
   a prettier lie than no highlight at all. Dashed still says coming soon; the tint says flagship. */
.app.soon.flagship{border-color:var(--accent)}
/* 3.3.0: an app this platform does not host: a plain card, not dimmed like "coming soon" (it is not waiting for anything) */
.app.own{background:transparent}
.app.own.flagship{border-color:var(--accent)}
/* CLOUDMETERS (D lane 3B): the coming-soon card's one field. `.app .btn{margin-top:auto}` pushes
   the last control to the bottom of a flex card, so the form takes that job instead when there is
   one — otherwise an "Own it outright" link and the form would both fight for the same space and
   the cards would stop lining up. Deliberately quiet: this is a card that cannot be bought yet,
   and a loud capture on it would out-shout the twelve that can. */
.app .notify{margin-top:auto;display:grid;gap:6px}
.app .notify input[type=email]{width:100%;box-sizing:border-box;padding:9px 11px;border-radius:var(--r);border:1px solid var(--line);background:var(--card);color:inherit;font:inherit;font-size:13px}
.app .notify input[type=email]:focus{outline:2px solid var(--accent);outline-offset:1px}
.app .notify button{padding:9px 12px;border-radius:var(--r);border:1px solid var(--line);background:transparent;color:inherit;font:inherit;font-size:12.5px;font-weight:600;cursor:pointer}
.app .notify button:hover{border-color:var(--accent)}
.app .btn.ghost + .notify{margin-top:10px}
/* Off-screen, not display:none — a label and a honeypot both have to exist for the things that
   read them (a screen reader; a form-filling bot) while neither takes space on the card. */
.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.tag{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;padding:4px 9px;border-radius:99px;align-self:flex-start}
.tag.live{background:var(--accentsoft);color:var(--accent)}
.tag.live i{width:6px;height:6px;border-radius:99px;background:var(--live);box-shadow:0 0 0 0 var(--live);animation:ping 1.6s infinite}
.tag.soon{background:var(--soft);color:var(--dim)}
@keyframes ping{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--live) 60%,transparent)}70%{box-shadow:0 0 0 8px transparent}100%{box-shadow:0 0 0 0 transparent}}
/* flow */
.flow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;align-items:stretch}
@media(max-width:980px){.flow{grid-template-columns:minmax(0,1fr)}}
.step{display:flex;flex-direction:column;gap:10px;min-width:0}
.step>.card,.step>.form{flex:1;display:flex;flex-direction:column}
.step .card .btn.block,.step .form .btn.block{margin-top:auto}
.step .k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.kv{display:grid;gap:6px;font-size:13.5px}
.kv div{display:grid;grid-template-columns:110px 1fr;gap:8px;padding:7px 0;border-bottom:1px solid var(--line)}
.kv span{color:var(--dim)}
.kv code{font-family:var(--mono);font-size:12.5px;word-break:break-all}
.badge{display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;padding:5px 11px;border-radius:99px;background:var(--soft);color:var(--dim);align-self:flex-start}
.badge.ok{background:var(--accentsoft);color:var(--accent)}
/* footer — real, on every board */
.foot{margin-top:64px;border-top:1px solid var(--line);padding:30px 0 44px;color:var(--dim);font-size:13.5px;background:var(--footbg)}
.foot .cols{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:20px}
@media(max-width:700px){.foot .cols{grid-template-columns:1fr 1fr}}
.foot b{display:block;color:var(--ink);margin-bottom:8px;font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase}
.foot a{display:block;text-decoration:none;color:var(--dim);margin:4px 0}
.foot .fline{margin-top:22px;padding-top:14px;border-top:1px solid var(--line);display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;color:var(--faint);font-size:12.5px}
/* annotation strip */
.anno{margin-top:0;background:#0b0d10;color:#b9c2d0;font-family:var(--mono);font-size:11.5px;line-height:1.6;padding:14px 28px;border-top:2px solid var(--accent)}
.anno b{color:#fff}
.anno span{color:#7ce8d8}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
.btn:not(.ghost)::after{content:"";position:absolute;inset:0;background:linear-gradient(110deg,transparent 30%,rgba(255,255,255,.45) 50%,transparent 70%);transform:translateX(-120%);animation:sheen 3.2s ease-in-out infinite}
@keyframes sheen{0%,60%{transform:translateX(-120%)}100%{transform:translateX(120%)}}
.btn:not(.ghost){box-shadow:0 10px 24px -12px rgba(79,70,229,.7)}
.hero{background:radial-gradient(60% 50% at 80% 10%,rgba(6,182,212,.14),transparent 60%),radial-gradient(40% 40% at 10% 80%,rgba(79,70,229,.10),transparent 60%)}
/* THE RAIL — pay → reserve → build → live; a pulse runs the dashed wire (the store's dash, Cloud's own rail) */
.rail{position:relative;padding:26px 8px 8px}
.rail svg{width:100%;height:auto;display:block}
.rail .wire{stroke:#c7cdea;stroke-width:3;stroke-dasharray:8 10;animation:dash 2.4s linear infinite}
@keyframes dash{to{stroke-dashoffset:-36}}
.rail .pulse{fill:#4f46e5;filter:drop-shadow(0 0 8px rgba(79,70,229,.9))}
.rail .pulse{animation:run 4.8s cubic-bezier(.4,0,.2,1) infinite}
@keyframes run{0%{transform:translateX(0)}30%{transform:translateX(178px)}55%{transform:translateX(356px)}85%,100%{transform:translateX(534px)}}
.rail .node{fill:#fff;stroke:#c7cdea;stroke-width:3}
.rail .node.lit{stroke:#4f46e5;animation:lit 4.8s infinite}
.rail .n2{animation-delay:1.4s}
.rail .n3{animation-delay:2.6s}
.rail .n4{animation-delay:4s}
@keyframes lit{0%,20%{stroke:#c7cdea;fill:#fff}30%,100%{stroke:#4f46e5;fill:#eef2ff}}
.rail .lab{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;fill:#4b5563}
.rail .lab.big{font-family:var(--display);font-size:14px;font-weight:700;letter-spacing:0;text-transform:none;fill:#0b0f1a}
.inst{margin-top:10px;border:1px solid #d5d9e3;border-radius:16px;padding:14px 16px;background:#fff;display:flex;justify-content:space-between;align-items:center;gap:10px;animation:breathe 4.8s ease-in-out infinite}
@keyframes breathe{0%,60%{box-shadow:0 0 0 0 rgba(16,185,129,0)}80%{box-shadow:0 0 0 10px rgba(16,185,129,.16),0 20px 40px -20px rgba(79,70,229,.5)}100%{box-shadow:0 0 0 0 rgba(16,185,129,0)}}
.inst code{font-family:var(--mono);font-size:12.5px}
.led{width:8px;height:8px;border-radius:99px;background:var(--live);display:inline-block;animation:ping 1.6s infinite}
/* the ownership promise as three stops on a filling track */
.promise{margin:34px 0 0;position:relative;display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(max-width:640px){.promise{grid-template-columns:1fr}}
.promise::before{content:"";position:absolute;left:0;right:0;top:-14px;height:4px;border-radius:99px;background:linear-gradient(90deg,#4f46e5,#06b6d4 60%,#10b981);background-size:200% 100%;animation:fill 6s linear infinite}
@keyframes fill{from{background-position:100% 0}to{background-position:0 0}}
.stop{background:#fff;border:1px solid var(--line);border-radius:14px;padding:14px 16px}
.stop b{display:block;font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin-bottom:4px}
.stop.own{border-color:#10b981;background:linear-gradient(180deg,#ecfdf5,#fff)}
.apps .app.live .tag.live{background:linear-gradient(120deg,#eef2ff,#ecfeff)}
/* ── the plane's own furniture, in A's system ─────────────────────────────────────────────── */
.alert{border-radius:var(--r);padding:12px 14px;margin:0 0 16px;font-size:14px;border:1px solid var(--line)}
.alert.ok{background:#ecfdf5;border-color:#a7f3d0;color:#065f46}
.alert.err{background:#fef2f2;border-color:#fecaca;color:#991b1b}
.muted{color:var(--dim)}.small{font-size:13px}
table.rows{width:100%;border-collapse:collapse;font-size:14px}
table.rows th{text-align:left;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);padding:0 0 8px}
table.rows td{padding:10px 0;border-top:1px solid var(--line);vertical-align:top}
/* .wall wears two hats: a centred card INSIDE the layout (the account sign-in), and the whole
   document on the standalone 404, which has no header or footer to sit between. */
.wall{max-width:560px;margin:12vh auto;text-align:center}
body.wall{display:grid;place-items:center;min-height:100vh;margin:0;padding:24px;max-width:none;box-sizing:border-box}
body.wall .card{max-width:520px;text-align:center}
.wall .brand{display:inline-flex;align-items:center;gap:8px;font-family:var(--display);font-weight:800;font-size:17px;text-decoration:none;color:var(--ink)}
.wall .brand b{color:var(--accent)}
body.wall h1{font-family:var(--display);font-weight:var(--hw);font-size:52px;letter-spacing:-.03em;margin:12px 0 6px}
.wall .eyebrow{margin-bottom:10px}
.field{display:grid;gap:6px}.field label{font-size:13px;font-weight:600}
/* Typeless <input> is the default in these views (`<input name="subdomain" required>`), and an
   [type=text] selector does NOT match an element with no type attribute — half the start form
   rendered as unstyled browser boxes beside styled ones. Select by exclusion instead. */
input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]),select{width:100%;box-sizing:border-box;background:var(--field);border:1px solid var(--line2);border-radius:var(--r);padding:11px 12px;font:inherit;font-size:14px;color:var(--ink)}
input:focus,select:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}

/* plane furniture the boards did not need to draw */
.footend{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;border-top:1px solid var(--line);margin-top:22px;padding-top:14px;font-size:12.5px;color:var(--faint)}
.btn.danger{background:transparent;color:#b91c1c;border:1px solid #fecaca}
.btn.danger:hover{background:#fef2f2}

/* The account's instance record. It is NOT the landing's .inst strip: that one is a single flex
   ROW (domain · running) and reusing it here made the card's kv block, button row and footnote
   into flex items — the footnote was squeezed to 65px and pushed 6px past a 390 viewport, which
   overflow-x:hidden then hid. A record card stacks. */
.instance{display:grid;gap:12px}
.instance + .instance{margin-top:14px}
.instance code{font-family:var(--mono);font-size:12.5px;word-break:break-word}
