/* ==========================================================================
   Fonts — self-hosted, Greek + Latin, variable (every weight in one file).
   Six files, 160 KB. No third-party request: a company selling GDPR
   compliance should not hand visitor IPs to a font CDN to draw a headline.
   ========================================================================== */
@font-face{font-family:"Commissioner";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("../fonts/commissioner-greek.woff2") format("woff2");
  unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}
@font-face{font-family:"Commissioner";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("../fonts/commissioner-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("../fonts/inter-greek.woff2") format("woff2");
  unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}
@font-face{font-family:"Inter";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:100 800;font-display:swap;
  src:url("../fonts/jetbrains-mono-greek.woff2") format("woff2");
  unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:100 800;font-display:swap;
  src:url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* ==========================================================================
   Tokens. Navy and grey are measured from the logo. Cyan is the accent, as
   the brief requires. Orange and red appear ONLY on blocked/warning states —
   never as decoration.
   ========================================================================== */
:root{
  --ink:#081522;--ink-2:#0C1E30;--ink-3:#112A42;
  --rule:#1B3247;--rule-lit:#2C4C6A;

  --navy:#004A77;--navy-lift:#0A6396;
  --cy:#00D4FF;--cy-soft:rgba(0,212,255,.14);--cy-deep:#0B658F;

  --block:#F2704F;--warn:#F0A85C;--ok:#4FD1A1;

  --paper:#F1F4F8;--card:#FFFFFF;--edge:#D8E0E8;--edge-2:#BECBD7;

  --on-dark:#E9EFF5;--on-dark-dim:#9DB2C6;--on-dark-faint:#6A849E;
  --on-paper:#0A1826;--on-paper-dim:#4A6076;

  --gap:clamp(4rem,7.5vw,7rem);
  --r:10px;--r-sm:6px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--on-paper);
  font:400 1rem/1.68 Inter,system-ui,-apple-system,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
h1,h2,h3,h4{font-family:Commissioner,Inter,system-ui,sans-serif;margin:0;font-weight:800;letter-spacing:-.03em;line-height:1.08}
h1{font-size:clamp(2rem,4.6vw,3.5rem);line-height:1.08}
h2{font-size:clamp(1.6rem,3vw,2.4rem);letter-spacing:-.028em}
h3{font-size:1.08rem;font-weight:600;letter-spacing:-.014em;line-height:1.34}
p{margin:0}
img,svg{max-width:100%}
a{color:var(--navy)}
.mono{font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace}
.wrap{max-width:78rem;margin:0 auto;padding:0 clamp(1rem,3.2vw,2.25rem)}
.sec{padding:var(--gap) 0}
.dark{background:var(--ink);color:var(--on-dark)}
.dark h1,.dark h2,.dark h3{color:var(--on-dark)}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

.tag{font-family:"JetBrains Mono",monospace;font-size:.7rem;font-weight:500;letter-spacing:.18em;
  text-transform:uppercase;color:var(--cy-deep);display:inline-flex;align-items:center;gap:.6rem;flex-wrap:wrap}
.dark .tag{color:var(--cy)}
.tag::before{content:"";width:1.6rem;height:1px;background:currentColor;opacity:.55;flex:none}
/* On narrow screens the rule wraps onto a line of its own and reads as a stray
   dash, so it goes away rather than sitting there looking like a mistake. */
@media (max-width:30rem){.tag::before{display:none}}
.lede{font-size:clamp(1rem,1.25vw,1.1rem);color:var(--on-paper-dim);max-width:34rem}
.dark .lede{color:var(--on-dark-dim)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:.55rem;padding:.85rem 1.4rem;
  border-radius:var(--r-sm);border:1px solid transparent;font:500 .9rem/1 Inter,sans-serif;
  text-decoration:none;cursor:pointer;transition:background .18s,border-color .18s,color .18s,transform .18s}
.btn-fill{background:var(--navy);color:#fff}
.btn-fill:hover{background:var(--navy-lift);transform:translateY(-1px)}
.btn-line{border-color:var(--edge-2);color:var(--on-paper);background:transparent}
.btn-line:hover{border-color:var(--navy);color:var(--navy)}
.dark .btn-fill{background:var(--cy);color:#04222F}
.dark .btn-fill:hover{background:#5AC6F0}
.dark .btn-line{border-color:var(--rule-lit);color:var(--on-dark)}
.dark .btn-line:hover{border-color:var(--cy);color:var(--cy)}
.arw{transition:transform .18s}
.btn:hover .arw,.go:hover .arw{transform:translateX(3px)}
:where(a,button,summary,[tabindex]):focus-visible{outline:2px solid var(--cy);outline-offset:3px;border-radius:var(--r-sm)}
.skip{position:absolute;left:-9999px}
.skip:focus{position:static;display:inline-block;margin:.6rem 1.5rem;color:var(--cy)}

/* ==========================================================================
   Header
   ========================================================================== */
.bar{position:sticky;top:0;z-index:60;background:rgba(8,21,34,.9);backdrop-filter:blur(14px);border-bottom:1px solid var(--rule)}
.bar-in{display:flex;align-items:center;gap:1.25rem;min-height:4.6rem}
.brand{display:flex;align-items:center;text-decoration:none;flex:none;
  /* the logo files expose these hooks; on dark we drive them, we never redraw the art */
  --logo-ring:#8FA6BC;--logo-word:#EAF1F8}
.brand .logo-full,.brand .logo-mark{display:block;height:clamp(2.1rem,2.9vw,2.7rem)}
.brand .logo-full svg,.brand .logo-mark svg{display:block;height:100%;width:auto}
.brand .logo-mark{display:none}
.bar nav{margin-inline:auto}
.bar nav ul{display:flex;gap:1.5rem;list-style:none;margin:0;padding:0;flex-wrap:wrap}
.bar nav a{font-size:.83rem;letter-spacing:.03em;color:var(--on-dark-dim);text-decoration:none;
  padding:.35rem 0;border-bottom:2px solid transparent;transition:color .18s,border-color .18s;display:block}
.bar nav a:hover,.bar nav a[aria-current="page"]{color:var(--on-dark);border-bottom-color:var(--cy)}
.menu-btn{display:none;background:none;border:1px solid var(--rule-lit);border-radius:var(--r-sm);
  color:var(--on-dark);padding:.55rem .7rem;cursor:pointer;line-height:0}
.menu-btn svg{width:1.15rem;height:1.15rem;stroke:currentColor;stroke-width:2;fill:none}
.menu-btn .x{display:none}
.menu-btn[aria-expanded="true"] .x{display:block}
.menu-btn[aria-expanded="true"] .b{display:none}

/* No JS: the menu button is useless, so hide it and let the nav wrap. */
.no-js .menu-btn{display:none!important}
@media (max-width:70rem){
  .bar-in{flex-wrap:wrap;padding-block:.7rem;gap:.8rem}
  .bar nav{order:3;flex-basis:100%;margin-inline:0}
  .bar nav ul{gap:.4rem 1.1rem}
  /* With JS the nav collapses behind the button. Without JS it simply wraps
     onto its own row and stays usable — the menu never depends on script. */
  .js .menu-btn{display:block;margin-left:auto}
  .js .bar nav{display:none}
  .js .bar nav.open{display:block}
  .js .bar nav.open ul{padding:.5rem 0 .3rem;gap:.15rem}
  .js .bar nav.open a{padding:.5rem 0;font-size:.9rem}
  .bar .btn-head{display:none}
}
@media (max-width:42rem){
  .brand .logo-full{display:none}
  .brand .logo-mark{display:block;height:2.4rem}
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero{padding:clamp(2.5rem,5vw,4.5rem) 0 clamp(3rem,6vw,5rem);position:relative;overflow:hidden}
.hero::after{content:"";position:absolute;inset:auto -20% -60% 40%;height:70%;
  background:radial-gradient(ellipse at center,rgba(0,74,119,.42),transparent 66%);pointer-events:none}
.hero .wrap{position:relative;z-index:1}
.hero-grid{display:grid;gap:clamp(2rem,3.5vw,3.2rem);grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);align-items:center}
@media (max-width:72rem){.hero-grid{grid-template-columns:1fr}}
.hero h1{margin:1.2rem 0 1.3rem}
.hero h1 .w{color:var(--cy);display:block}
.cta-row{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:2rem}
.oss{margin-top:1.9rem;display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .7rem;font-size:.78rem;color:var(--on-dark-faint)}
.oss .chip{border:1px solid var(--rule);border-radius:2rem;padding:.32rem .8rem;color:var(--on-dark-dim);
  text-decoration:none;transition:border-color .18s,color .18s;word-break:break-all}
a.chip:hover{border-color:var(--cy);color:var(--cy)}

/* ==========================================================================
   NFTBan operations dashboard — the one technical visual.
   Renders complete without JavaScript; JS only rotates the event stream.
   ========================================================================== */
.dash{background:linear-gradient(180deg,#0C2033,#091A2A);border:1px solid var(--rule);border-radius:var(--r);
  overflow:hidden;box-shadow:0 34px 80px -36px rgba(0,0,0,.9)}
.dash-top{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;padding:.85rem 1rem;border-bottom:1px solid var(--rule)}
.dash-top .mk{width:1.55rem;height:1.55rem;border-radius:50%;background:var(--cy-soft);border:1px solid var(--rule-lit);
  display:grid;place-items:center;flex:none}
.dash-top .mk svg{width:.85rem;height:.85rem;stroke:var(--cy);stroke-width:1.9;fill:none}
.dash-top h2{font-size:.98rem;font-weight:600;color:var(--on-dark);margin-right:auto}
.demo{font-family:"JetBrains Mono",monospace;font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  border:1px solid var(--warn);color:var(--warn);border-radius:2rem;padding:.24rem .6rem;white-space:nowrap}
.dash-grid{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,.95fr) minmax(0,1.4fr);gap:1px;background:var(--rule)}
@media (max-width:60rem){.dash-grid{grid-template-columns:1fr}}
.pane{background:#0A1B2B;padding:.95rem 1rem 1.05rem;min-width:0}
.pane h3{font-family:"JetBrains Mono",monospace;font-size:.62rem;font-weight:500;letter-spacing:.15em;
  text-transform:uppercase;color:var(--on-dark-faint);margin-bottom:.8rem}

.status{display:flex;align-items:center;gap:.6rem;padding:.7rem .8rem;border:1px solid rgba(79,209,161,.3);
  background:rgba(79,209,161,.07);border-radius:var(--r-sm);margin-bottom:.9rem}
.status svg{width:1.3rem;height:1.3rem;stroke:var(--ok);stroke-width:1.7;fill:none;flex:none}
.status b{display:block;font:600 .82rem/1.3 Inter,sans-serif;color:var(--ok)}
.status span{display:block;font-size:.68rem;color:var(--on-dark-faint);line-height:1.4}

.sets{list-style:none;margin:0;padding:0;display:grid;gap:.42rem}
.sets li{display:flex;align-items:center;gap:.55rem;font-family:"JetBrains Mono",monospace;font-size:.72rem;color:var(--on-dark-dim)}
.sets .d{width:5px;height:5px;border-radius:50%;background:var(--ok);flex:none}
.sets .st{margin-left:auto;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ok)}

.topo{width:100%;height:auto;display:block}
.topo text{font-family:"JetBrains Mono",monospace;font-size:8.5px;fill:#9DB2C6;letter-spacing:.5px}
.topo .lbl{font-size:7px;fill:#6A849E}
.topo .ln{stroke:#2C4C6A;stroke-width:1.1;fill:none}
.topo .nd{fill:#102438;stroke:#2C4C6A;stroke-width:1.1}
.topo .hot{stroke:var(--cy);fill:rgba(0,212,255,.1)}
.topo .ic{stroke:#9DB2C6;stroke-width:1.2;fill:none}
.topo .ic-cy{stroke:var(--cy);stroke-width:1.3;fill:none}
.topo .flow{stroke:var(--cy);stroke-width:1.4;stroke-dasharray:3 6;fill:none;opacity:.85}

.feed{list-style:none;margin:0;padding:0;display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);border-radius:var(--r-sm);overflow:hidden}
.feed li{background:#0A1B2B;display:grid;grid-template-columns:3.2rem minmax(0,1fr) auto;gap:.5rem;
  align-items:center;padding:.62rem .65rem;font-size:.71rem}
.feed .t{font-family:"JetBrains Mono",monospace;color:var(--on-dark-faint);font-size:.66rem;align-self:start;padding-top:.1rem}
.feed .ev{min-width:0}
/* Titles wrap rather than truncate — "SQL inj…" tells the reader nothing. */
.feed .ev b{display:block;font-weight:500;font-size:.72rem;line-height:1.3;color:var(--on-dark)}
.feed .ev span{display:block;font-family:"JetBrains Mono",monospace;font-size:.64rem;color:var(--on-dark-faint);margin-top:.12rem}
.vd{align-self:start}
.vd{font-family:"JetBrains Mono",monospace;font-size:.57rem;letter-spacing:.09em;padding:.2rem .45rem;
  border-radius:3px;white-space:nowrap}
.vd-b{color:var(--block);border:1px solid rgba(242,112,79,.4);background:rgba(242,112,79,.09)}
.vd-c{color:var(--warn);border:1px solid rgba(240,168,92,.4);background:rgba(240,168,92,.09)}
.dash-foot{display:flex;flex-wrap:wrap;gap:.4rem 1.4rem;align-items:center;padding:.75rem 1rem;border-top:1px solid var(--rule);
  font-family:"JetBrains Mono",monospace;font-size:.66rem;color:var(--on-dark-faint)}
.dash-foot b{color:var(--on-dark-dim);font-weight:500}
/* The honesty caption sits outside the panel: inside, it fought the foot row
   for space and opened a dead band across the dashboard. */
.dash-cap{margin-top:.7rem;font-family:"JetBrains Mono",monospace;font-size:.66rem;line-height:1.5;
  color:var(--warn);opacity:.92;display:flex;gap:.5rem;align-items:flex-start}
.dash-cap::before{content:"▲";font-size:.6rem;line-height:1.6;flex:none}

/* ==========================================================================
   Vendor strip
   ========================================================================== */
.vend{background:var(--ink-2);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.vend .wrap{display:flex;flex-wrap:wrap;align-items:center;gap:1rem clamp(1.2rem,2.6vw,2.4rem);padding-block:1.4rem}
.vend .lbl{font-family:"JetBrains Mono",monospace;font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-dark-faint);flex:none;max-width:9rem;line-height:1.55}
.vend ul{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem clamp(1rem,2.2vw,2rem);list-style:none;margin:0;padding:0}
.vend li{font-family:Commissioner,sans-serif;font-weight:600;font-size:.95rem;color:var(--on-dark-dim);
  opacity:.86;transition:opacity .2s,color .2s}
.vend li:hover{opacity:1;color:var(--on-dark)}

/* ==========================================================================
   Services
   ========================================================================== */
.intro-grid{display:grid;gap:clamp(2rem,3.5vw,3.2rem);grid-template-columns:minmax(0,.72fr) minmax(0,1.6fr);align-items:start}
@media (max-width:70rem){.intro-grid{grid-template-columns:1fr}}
.intro h2{margin:1rem 0}
.intro .btn{margin-top:1.6rem}
.cards{display:grid;gap:1.05rem;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr))}
.cd{position:relative;background:var(--card);border:1px solid var(--edge);border-radius:var(--r);
  padding:1.5rem 1.35rem 1.3rem;display:flex;flex-direction:column;gap:.6rem;
  transition:border-color .2s,box-shadow .2s,transform .2s}
.cd:hover{border-color:var(--navy);box-shadow:0 16px 36px -20px rgba(0,74,119,.4);transform:translateY(-3px)}
.cd .ic{width:2.5rem;height:2.5rem;border-radius:var(--r-sm);display:grid;place-items:center;
  background:#EAF2F8;border:1px solid #D3E3EF;margin-bottom:.3rem}
.cd .ic svg{width:1.2rem;height:1.2rem;stroke:var(--navy);stroke-width:1.6;fill:none}
.cd p{font-size:.89rem;color:var(--on-paper-dim)}
.cd .go{margin-top:auto;padding-top:.9rem;font-size:.83rem;font-weight:500;text-decoration:none;color:var(--navy);
  display:inline-flex;gap:.4rem;align-items:center}
.cd-own{border-color:var(--navy);box-shadow:0 0 0 1px rgba(0,74,119,.18)}
.cd-own .ic{background:#E2F1FA;border-color:#BEDDF0}
.own-b{position:absolute;top:.9rem;right:.9rem;font-family:"JetBrains Mono",monospace;font-size:.57rem;
  letter-spacing:.13em;text-transform:uppercase;color:var(--cy-deep);background:#E2F1FA;border:1px solid #BEDDF0;
  border-radius:2rem;padding:.22rem .55rem}

/* ==========================================================================
   Proof
   ========================================================================== */
.proof-head{text-align:center;max-width:44rem;margin:0 auto 2.6rem}
.proof-head h2{margin:.9rem 0 .7rem}
.proof-head .lede{margin-inline:auto}
.proof-head .tag{justify-content:center}
.proofs{display:grid;gap:1.05rem;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr))}
.pf{background:var(--ink-2);border:1px solid var(--rule);border-radius:var(--r);padding:1.35rem 1.3rem;
  display:flex;gap:.9rem;align-items:flex-start;transition:border-color .2s}
.pf:hover{border-color:var(--rule-lit)}
.pf .ic{width:2.4rem;height:2.4rem;border-radius:var(--r-sm);background:var(--cy-soft);border:1px solid var(--rule-lit);
  display:grid;place-items:center;flex:none}
.pf .ic svg{width:1.15rem;height:1.15rem;stroke:var(--cy);stroke-width:1.55;fill:none}
.pf h3{font-size:.95rem;margin-bottom:.35rem}
.pf p{font-size:.82rem;color:var(--on-dark-dim);line-height:1.55}
.pf a{color:var(--cy);text-decoration:none;border-bottom:1px solid rgba(0,212,255,.35);word-break:break-all}
.pf a:hover{border-bottom-color:var(--cy)}
/* Four spec cards read as a clean 2×2 block; auto-fit left one stranded alone. */
.spec-2x2{grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:44rem){.spec-2x2{grid-template-columns:1fr}}

/* ==========================================================================
   Case studies
   ========================================================================== */
.cases{display:grid;gap:1.05rem;grid-template-columns:repeat(auto-fit,minmax(13.5rem,1fr))}
.cs{background:var(--card);border:1px solid var(--edge);border-radius:var(--r);overflow:hidden;
  display:flex;flex-direction:column;transition:border-color .2s,box-shadow .2s,transform .2s}
.cs:hover{border-color:var(--navy);box-shadow:0 16px 36px -20px rgba(0,74,119,.4);transform:translateY(-3px)}
/* Abstract CSS artwork instead of stock photography: nothing to license, nothing to load. */
.cs .art{height:7.5rem;position:relative;background:linear-gradient(135deg,#0C2033,#0A1826);overflow:hidden}
.cs .art svg{position:absolute;inset:0;width:100%;height:100%}
.cs .bd{padding:1.3rem 1.3rem 1.2rem;display:flex;flex-direction:column;gap:.55rem;flex:1}
.cs h3{font-size:1rem}
.cs p{font-size:.87rem;color:var(--on-paper-dim)}
.cs .go{margin-top:auto;padding-top:.8rem;font-size:.78rem;font-weight:500;letter-spacing:.06em;text-transform:uppercase;
  text-decoration:none;color:var(--navy);display:inline-flex;gap:.4rem;align-items:center;font-family:"JetBrains Mono",monospace}
.ind{display:inline-block;margin-top:1.4rem;font-size:.8rem;color:var(--on-paper-dim);
  background:#E4EAF1;border-left:2px solid var(--edge-2);border-radius:var(--r-sm);padding:.7rem .95rem}
.center{text-align:center;margin-top:2.2rem}

/* ==========================================================================
   Compliance (carried over from v4)
   ========================================================================== */
.frames{display:grid;gap:1.05rem;grid-template-columns:repeat(auto-fit,minmax(17rem,1fr))}
.fr{background:var(--card);border:1px solid var(--edge);border-left:2px solid var(--navy);border-radius:var(--r);padding:1.45rem 1.35rem}
.fr h3{margin-bottom:.5rem}
.fr > p{font-size:.88rem;color:var(--on-paper-dim)}
.fr .law{display:block;margin-top:.9rem;padding-top:.75rem;border-top:1px solid var(--edge);
  font-family:"JetBrains Mono",monospace;font-size:.69rem;line-height:1.62;color:var(--cy-deep)}
.note{margin-top:1.6rem;padding:1rem 1.15rem;background:#E4EAF1;border-left:2px solid var(--edge-2);
  border-radius:var(--r-sm);font-size:.86rem;color:var(--on-paper-dim)}

/* ==========================================================================
   Contact / footer
   ========================================================================== */
.panel{background:var(--ink);color:var(--on-dark);border-radius:var(--r);padding:clamp(1.8rem,4vw,3.2rem);
  display:grid;gap:clamp(1.8rem,3.5vw,3rem);grid-template-columns:repeat(auto-fit,minmax(16.5rem,1fr));align-items:start}
.panel h2{color:var(--on-dark);margin:1rem 0}
.info{margin:0;display:grid;gap:1.05rem}
.info dt{font-family:"JetBrains Mono",monospace;font-size:.64rem;letter-spacing:.15em;text-transform:uppercase;color:var(--on-dark-faint)}
.info dd{margin:.28rem 0 0;font-size:.92rem;color:var(--on-dark)}
.info a{color:var(--on-dark);text-decoration:none;border-bottom:1px solid var(--rule-lit)}
.info a:hover{color:var(--cy);border-bottom-color:var(--cy)}
footer{background:var(--ink);color:var(--on-dark-faint);border-top:1px solid var(--rule);padding:2.3rem 0;font-size:.81rem}
footer .wrap{display:flex;flex-wrap:wrap;gap:.8rem 2rem;justify-content:space-between;align-items:center}
footer a{color:var(--on-dark-dim);text-decoration:none}
footer a:hover{color:var(--cy)}

/* ==========================================================================
   Motion
   ========================================================================== */
.rise{opacity:0;transform:translateY(14px)}
.rise.in{opacity:1;transform:none;transition:opacity .6s cubic-bezier(.22,.61,.36,1),transform .6s cubic-bezier(.22,.61,.36,1)}
.no-js .rise,
.reveal-failsafe .rise{opacity:1;transform:none}
.hero .tag,.hero h1,.hero .lede,.hero .cta-row,.hero .oss,.hero .dash-wrap{animation:enter .75s cubic-bezier(.22,.61,.36,1) both}
.hero h1{animation-delay:.07s}.hero .lede{animation-delay:.16s}
.hero .cta-row{animation-delay:.26s}.hero .oss{animation-delay:.34s}.hero .dash-wrap{animation-delay:.18s}
@keyframes enter{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.flow{animation:dash 2.4s linear infinite}
@keyframes dash{to{stroke-dashoffset:-18}}
.blip{animation:blip 2.6s ease-in-out infinite}
@keyframes blip{0%,100%{opacity:.3}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .rise{opacity:1!important;transform:none!important}
}

/* ==========================================================================
   v6 — MOTION LAYER
   Four additions over v5: the hero traffic field, the decrypting headline,
   the vendor marquee, and the artwork hover. Everything here is additive;
   no v5 rule was rewritten, so the page still renders complete without it.
   ========================================================================== */

/* --- 1. The traffic field ------------------------------------------------
   Packets cross the hero, meet the nftables chain, and the hostile ones stop
   there. It sits behind the copy at low contrast: it is atmosphere, not a
   chart, and it must never compete with the headline for attention. */
.hero-fx{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:0;transition:opacity 1.4s ease;
  /* faded out over the left column: moving pixels under a headline cost more
     legibility than they buy atmosphere */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,transparent 34%,#000 58%,#000 100%);
          mask-image:linear-gradient(90deg,transparent 0,transparent 34%,#000 58%,#000 100%)}
.hero-fx.on{opacity:1}
.hero-fx canvas{display:block;width:100%;height:100%}
/* below the two-column breakpoint the copy sits over the whole width, so the
   field pulls back further still */
@media (max-width:72rem){.hero-fx.on{opacity:.42}}

/* --- 2. The headline decrypts -------------------------------------------
   v5 faded the whole h1 in as one block; that entrance is switched off here
   so each line can resolve on its own. */
.js .hero h1{animation:none}
.hero h1 .ln{display:block}
/* the second line goes inline-block so the caret can sit beside it instead of
   dropping onto a line of its own */
.hero h1 .ln.w{display:inline-block}
/* Held back for the decrypt — but never hostage to it. If the script throws
   before the sequence starts, this failsafe still reveals the headline. A
   blank hero is a far worse outcome than a missed effect. */
.js .hero h1 .ln{opacity:0;animation:failsafe 0s linear 2.5s forwards}
.js .hero h1 .ln.live{opacity:1}
@keyframes failsafe{to{opacity:1}}
/* glyphs still resolving are data, so they are set as data */
.hero h1 .sc{color:var(--cy-deep);font-family:"JetBrains Mono",monospace;font-weight:400}
.hero h1 .caret{display:inline-block;width:.055em;height:.78em;background:var(--cy);
  vertical-align:-.04em;margin-left:.08em;opacity:0}
.js .hero h1.typing .caret{opacity:1;animation:caret 1s steps(1) infinite}
@keyframes caret{50%{opacity:0}}

/* the policy sets report in one at a time rather than arriving pre-filled */
.js .sets li{opacity:.3;transition:opacity .45s ease}
.js .sets li.up{opacity:1}
.js .sets li .st{opacity:0;transition:opacity .4s ease}
.js .sets li.up .st{opacity:1}

/* --- 3. Vendor marquee ---------------------------------------------------
   Authentic marks, one ink, one optical height, moving continuously. The
   names live in aria-label: this is a row of marks, not a line of words. */
.vend{overflow:hidden}
.vend .wrap{display:flex;flex-wrap:nowrap;align-items:center;gap:clamp(1rem,2.4vw,2rem);padding-block:1.5rem}
.vend .lbl{flex:none}
.v-track{flex:1;min-width:0;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent)}
/* Each row translates by 100% of ITSELF, not of the track. The two rows are
   identical and sit end to end, so when row A has travelled its own width,
   row B is exactly where A began — a seamless loop that does not depend on
   the flex parent resolving to max-content (it does not, reliably). */
.v-marquee{display:flex;width:max-content}
.v-marquee:hover .v-row,.v-marquee:focus-within .v-row{animation-play-state:paused}
@keyframes marquee{to{transform:translateX(-100%)}}
.v-row{display:flex;align-items:center;list-style:none;margin:0;flex:none;
  gap:clamp(2.2rem,4.4vw,3.6rem);padding:0 clamp(2.2rem,4.4vw,3.6rem) 0 0;
  animation:marquee 46s linear infinite}
.v-item{flex:none;display:flex;align-items:center}
.v-mark{display:block;width:auto;color:var(--on-dark-dim);opacity:.66;
  transition:opacity .25s ease,color .25s ease,transform .25s ease}
.v-word .v-mark{height:calc(1.15rem * var(--s,1))}
.v-glyph .v-mark{height:1.7rem}
.v-item:hover .v-mark{opacity:1;color:var(--cy);transform:translateY(-2px)}
@media (max-width:52rem){
  .vend .wrap{flex-wrap:wrap}
  .vend .lbl{flex:1 0 100%;max-width:none}
}

/* --- 4. Artwork hover ----------------------------------------------------
   The template this replaces slid a caption drawer up over the image. Here
   the art zooms, a veil wipes in diagonally and a hairline scans down it —
   a scan, which is what this company actually does. */
.cs .art svg{transition:transform .75s cubic-bezier(.16,1,.3,1)}
.cs:hover .art svg,.cs:focus-within .art svg{transform:scale(1.09)}
.cs .veil{position:absolute;inset:0;
  background:linear-gradient(160deg,rgba(0,212,255,.32),rgba(0,74,119,.8));
  clip-path:inset(0 0 100% 0);transition:clip-path .55s cubic-bezier(.16,1,.3,1)}
.cs:hover .veil,.cs:focus-within .veil{clip-path:inset(0 0 0 0)}
.cs .scan{position:absolute;left:0;right:0;top:0;height:1px;background:var(--cy);
  box-shadow:0 0 12px 1px var(--cy);opacity:0}
.cs:hover .scan,.cs:focus-within .scan{animation:scanline 1.05s cubic-bezier(.16,1,.3,1)}
@keyframes scanline{0%{opacity:0;transform:translateY(0)}14%{opacity:.9}100%{opacity:0;transform:translateY(7.5rem)}}
.cs .over{position:absolute;left:1.1rem;right:1.1rem;bottom:.85rem;color:#fff;
  font-family:"JetBrains Mono",monospace;font-size:.63rem;letter-spacing:.14em;text-transform:uppercase;
  opacity:0;transform:translateY(10px);
  transition:opacity .42s cubic-bezier(.16,1,.3,1) .08s,transform .42s cubic-bezier(.16,1,.3,1) .08s}
.cs:hover .over,.cs:focus-within .over{opacity:1;transform:none}

/* the partner-facing card closes the grid as a full-width band */
.cd-wide{grid-column:1/-1;flex-direction:row;align-items:flex-start;gap:1.2rem}
.cd-wide .ic{margin-bottom:0;flex:none}
.cd-wide .cd-body{display:flex;flex-direction:column;gap:.55rem;flex:1;min-width:0}
.cd-wide .cd-body p{margin-top:0;max-width:52rem}
.cd-wide .go{margin-top:.35rem;padding-top:0}
@media (max-width:34rem){.cd-wide{flex-direction:column}.cd-wide .ic{margin-bottom:.3rem}}

/* service cards get a restrained version of the same idea */
.cd{overflow:hidden}
.cd::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--cy);
  transform:scaleX(0);transform-origin:left;transition:transform .45s cubic-bezier(.16,1,.3,1)}
.cd:hover::before,.cd:focus-within::before{transform:scaleX(1)}
.cd .ic{transition:transform .35s cubic-bezier(.16,1,.3,1),background .25s}
.cd:hover .ic{transform:translateY(-2px) rotate(-4deg)}

/* what we actually take on, per framework */
.fr ul{margin:.85rem 0 0;padding:0;list-style:none;display:grid;gap:.4rem}
.fr li{position:relative;padding-left:1.1rem;font-size:.83rem;color:var(--on-paper-dim);line-height:1.5}
.fr li::before{content:"";position:absolute;left:0;top:.55em;width:.42rem;height:.42rem;
  border-radius:50%;background:var(--cy-deep);opacity:.5}

@media (prefers-reduced-motion:reduce){
  /* the marquee cannot simply stop — half its marks would sit outside the
     clip. It becomes a plain wrapped row instead. */
  .v-track{overflow:visible;-webkit-mask-image:none;mask-image:none}
  .v-marquee{width:auto;flex-wrap:wrap;justify-content:center}
  .v-row{flex-wrap:wrap;justify-content:center;padding-right:0;gap:1.4rem 2.2rem}
  .v-marquee .v-row + .v-row{display:none}
  .js .hero h1 .ln{opacity:1}
  .js .sets li,.js .sets li .st{opacity:1}
  .hero-fx{opacity:1}
}
.no-js .hero h1 .ln{opacity:1}

/* ==========================================================================
   v6.1 — COLOUR LIFT
   Every pair below was checked against WCAG before it was written in. Two
   values from the brief did not survive that check and were tempered:
     - the CTA gradient end #0072FF gave 3.80:1 with dark label text (needs
       4.5); #0095F5 gives 5.19:1 and looks the same at a glance.
     - flat #00F2FE / #00C6FF card borders measured 2.0-2.5:1 on white, so
       each border is a gradient that ends deep enough to read as a line.
   The electric cyan is a DARK-GROUND colour only: #00D4FF on white is
   1.77:1, so paper keeps --cy-deep. Amber stays out of the dark sections,
   where it still means "caution".
   ========================================================================== */

/* headings go pure white on dark */
.dark h1,.dark h2,.dark h3{color:#fff}

/* CTAs become gradient pills with a glow */
.btn{border-radius:2rem;font-weight:600}
.btn-fill{background:linear-gradient(135deg,#0A6396 0%,#004A77 100%);color:#fff;
  box-shadow:0 4px 18px rgba(0,74,119,.22)}
.btn-fill:hover{background:linear-gradient(135deg,#0C74AF 0%,#005A8F 100%);
  transform:translateY(-2px);box-shadow:0 8px 26px rgba(0,74,119,.34)}
.dark .btn-fill{background:linear-gradient(135deg,#2ED8FF 0%,#0095F5 100%);color:#04222F;
  box-shadow:0 4px 20px rgba(0,212,255,.3)}
.dark .btn-fill:hover{background:linear-gradient(135deg,#4CE0FF 0%,#12A4FF 100%);
  transform:translateY(-2px);box-shadow:0 8px 28px rgba(0,212,255,.46)}

/* colour-coded compliance frameworks */
.fr{position:relative;overflow:hidden;border-left:1px solid var(--edge);
  transition:transform .3s cubic-bezier(.16,1,.3,1),box-shadow .3s ease,border-color .3s ease}
.fr::before{content:"";position:absolute;left:0;right:0;top:0;height:4px;background:var(--fw)}
.fr:hover{transform:translateY(-5px);border-color:var(--fw-solid);
  box-shadow:0 18px 34px -16px var(--fw-glow)}
.fr-nis2{--fw:linear-gradient(90deg,#00E5FF,#0086C4);--fw-solid:#0099CC;
  --fw-glow:rgba(0,153,204,.55);--fw-ink:#0369A1;--fw-tint:rgba(0,198,255,.10)}
.fr-dora{--fw:linear-gradient(90deg,#A855F7,#5B47D6);--fw-solid:#7E4BE8;
  --fw-glow:rgba(124,58,237,.5);--fw-ink:#7E22CE;--fw-tint:rgba(168,85,247,.12)}
.fr-iso{--fw:linear-gradient(90deg,#34E0A1,#048257);--fw-solid:#059669;
  --fw-glow:rgba(5,150,105,.48);--fw-ink:#047857;--fw-tint:rgba(16,185,129,.10)}
.fr-gdpr{--fw:linear-gradient(90deg,#FFC02E,#B8690A);--fw-solid:#D97706;
  --fw-glow:rgba(217,119,6,.45);--fw-ink:#B45309;--fw-tint:rgba(245,158,11,.12)}
.fr li::before{background:var(--fw-solid);opacity:.7}

/* legal references become chips instead of a run of grey mono text */
.fr .law{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem;
  margin-top:1rem;padding-top:.85rem;border-top:1px solid var(--edge);
  font-family:Inter,sans-serif;font-size:.78rem;color:var(--on-paper-dim);letter-spacing:0}
.fr .pill{font-family:"JetBrains Mono",monospace;font-size:.65rem;font-weight:600;
  letter-spacing:.03em;background:var(--fw-tint);color:var(--fw-ink);
  border-radius:2rem;padding:.32rem .72rem;white-space:nowrap}
.fr .scope{flex:1 0 100%;font-size:.75rem;line-height:1.5;color:var(--on-paper-dim)}

/* the contact block gets depth and a glow rather than a flat navy fill */
.panel{position:relative;overflow:hidden;border:1px solid rgba(255,255,255,.08);
  background:linear-gradient(140deg,#0A1826 0%,#122A47 55%,#161B3F 100%)}
.panel::after{content:"";position:absolute;top:-42%;right:-14%;width:26rem;height:26rem;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(0,212,255,.17) 0%,rgba(0,212,255,0) 70%)}
.panel > *{position:relative;z-index:1}

/* ==========================================================================
   v7 — ART DIRECTION
   Same architecture, same content, same honesty rules. What changes is the
   staging: more air, heavier type, more depth, and hover that rewards.
   ========================================================================== */

/* --- 1. Rhythm. The page read cramped because the measure was tight and the
       section gap was doing all the separating on its own. --- */
:root{--gap:clamp(5rem,9vw,9.5rem)}
.wrap{max-width:82rem;padding:0 clamp(1.25rem,4vw,3rem)}

/* --- 2. Type with authority. Commissioner is variable to 900, so the weight
       was available all along and simply unused. --- */
h1{font-size:clamp(2.4rem,4.6vw,3.9rem);font-weight:900;letter-spacing:-.042em;line-height:1.03}
h2{font-size:clamp(1.95rem,3.7vw,3rem);font-weight:900;letter-spacing:-.038em;line-height:1.06}
h3{font-size:1.14rem;font-weight:700;letter-spacing:-.022em}
.lede{font-size:clamp(1.04rem,1.3vw,1.2rem);line-height:1.64;max-width:36rem}
.tag{font-size:.72rem;font-weight:600;letter-spacing:.24em}
.tag::before{width:2.2rem;height:2px;opacity:.75}
.btn{padding:1rem 1.7rem;font-size:.93rem}

.hero{padding:clamp(3.5rem,6.5vw,6rem) 0 clamp(4rem,7.5vw,6.5rem)}
/* the heavier headline needs a wider column or it strands single words */
.hero-grid{gap:clamp(2.5rem,4.5vw,4rem);grid-template-columns:minmax(0,.95fr) minmax(0,1.16fr)}
@media (max-width:72rem){.hero-grid{grid-template-columns:1fr}}
.hero h1{margin:1.4rem 0 1.5rem}
.hero h1 .ln{text-wrap:balance}
.cta-row{margin-top:2.4rem}

/* --- 3. Vendor marquee: bigger marks, real air, smoother loop.
       The penguin and the Ubiquiti glyph are the only two square marks, so
       they read small next to wordmarks and collided at the loop seam. Glyphs
       are now sized up, the gap is roughly half again as wide, and a wordmark
       closes the row so two glyphs never meet. --- */
.vend{background:linear-gradient(180deg,#0A1B2C 0%,#0C1E30 100%)}
.vend .wrap{padding-block:2.2rem;gap:clamp(1.5rem,3.2vw,3rem)}
.vend .lbl{font-size:.66rem;letter-spacing:.2em;color:var(--on-dark-dim);max-width:10rem;line-height:1.6}
.v-track{-webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.v-row{gap:clamp(3.4rem,6.5vw,5.8rem);padding:0 clamp(3.4rem,6.5vw,5.8rem) 0 0;animation-duration:64s}
.v-glyph .v-mark{height:2.45rem}
.v-word .v-mark{height:1.32rem}
.v-mark{color:#C3D6E7;opacity:.58;
  transition:opacity .3s ease,color .3s ease,transform .35s cubic-bezier(.16,1,.3,1),filter .3s ease}
.v-item:hover .v-mark{opacity:1;color:#00D4FF;transform:translateY(-3px) scale(1.07);
  filter:drop-shadow(0 0 12px rgba(0,212,255,.55))}

/* --- 4. Services: rebalance. The intro column was taking a third of the row
       and squeezing the grid; it now takes about a quarter. --- */
.intro-grid{grid-template-columns:minmax(0,.78fr) minmax(0,2fr);gap:clamp(2.5rem,4.5vw,4.5rem)}
@media (max-width:70rem){.intro-grid{grid-template-columns:1fr}}
.intro h2{margin:1.1rem 0 1.2rem}
.intro .btn{margin-top:2rem}
/* Inside the narrow intro column (NFTBan still uses it) the display size
   shatters into one-word lines. Scope it down there only. */
.intro-grid .intro h2{font-size:clamp(1.75rem,2.7vw,2.45rem);letter-spacing:-.034em;
  line-height:1.1;text-wrap:balance}
@media (max-width:70rem){
  .intro-grid .intro h2{font-size:clamp(1.95rem,3.7vw,3rem);letter-spacing:-.038em}
}

/* full-width intro block above a full-width grid */
.intro-top{max-width:56rem;margin-bottom:clamp(2.6rem,4.5vw,4.2rem)}
.intro-top h2{text-wrap:balance;margin:1.1rem 0 1.15rem}
.intro-top .lede{max-width:46rem}
.intro-top .btn{margin-top:1.9rem}
#services .cards,#cases .cases{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:64rem){#services .cards,#cases .cases{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:42rem){#services .cards,#cases .cases{grid-template-columns:1fr}}
.cards{gap:1.5rem;grid-template-columns:repeat(auto-fit,minmax(16.5rem,1fr))}
.cd{padding:1.9rem 1.7rem 1.7rem;gap:.7rem;border-radius:16px;
  box-shadow:0 1px 2px rgba(10,24,38,.05);
  transition:transform .38s cubic-bezier(.16,1,.3,1),box-shadow .38s ease,border-color .3s ease}
.cd::before{height:3px;background:linear-gradient(90deg,#00D4FF,#0095F5)}
.cd .ic{width:2.9rem;height:2.9rem;border-radius:12px;
  transition:transform .4s cubic-bezier(.16,1,.3,1),background .3s ease,border-color .3s ease}
.cd .ic svg{width:1.35rem;height:1.35rem}
.cd p{font-size:.92rem;line-height:1.62}
.cd:hover{transform:translateY(-7px);border-color:#AFCFE4;
  box-shadow:0 28px 50px -24px rgba(0,74,119,.5),0 0 0 1px rgba(0,148,200,.16)}
.cd:hover .ic{transform:translateY(-3px) rotate(-6deg) scale(1.07);background:#DBEEFB;border-color:#A9D6EE}

/* the proprietary product should not look like the sixth item on a list */
.cd-own{border-color:#7FC7E8;background:linear-gradient(168deg,#FFFFFF 0%,#F3FAFE 100%);
  box-shadow:0 0 0 1px rgba(0,148,200,.2),0 20px 44px -26px rgba(0,74,119,.5)}
.cd-own::before{transform:scaleX(1)}
.cd-own .ic{background:linear-gradient(145deg,#DCF2FD,#BEE6F8);border-color:#93D1EE}
.cd-own:hover{box-shadow:0 0 0 1px rgba(0,148,200,.3),0 32px 56px -24px rgba(0,74,119,.55)}

/* --- 5. NFTBan reads as a product section, with its own light --- */
#nftban{position:relative;overflow:hidden;
  background:linear-gradient(168deg,#0A1F36 0%,#0C2542 42%,#081522 100%)}
#nftban::before{content:"";position:absolute;top:-16%;right:-10%;width:40rem;height:40rem;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(0,212,255,.17) 0%,rgba(0,212,255,0) 68%)}
#nftban .wrap{position:relative;z-index:1}
/* NFTBan keeps the two-column layout, but the copy column needs enough width
   for its two CTAs to sit on one line, and the grid should centre against it
   rather than hang from the top. */
#nftban .intro-grid{grid-template-columns:minmax(0,1fr) minmax(0,1.14fr);align-items:center}
@media (max-width:70rem){#nftban .intro-grid{grid-template-columns:1fr;align-items:start}}
#nftban .intro h2{font-size:clamp(2.2rem,4.2vw,3.3rem);letter-spacing:-.04em}
#nftban .intro .lede{max-width:33rem}
.proofs{gap:1.3rem}
.pf{padding:1.75rem 1.6rem;border-radius:14px;gap:1.05rem;
  background:linear-gradient(155deg,rgba(255,255,255,.06),rgba(255,255,255,.016));
  border:1px solid rgba(255,255,255,.09);
  transition:transform .38s cubic-bezier(.16,1,.3,1),border-color .3s ease,box-shadow .38s ease}
.pf:hover{transform:translateY(-5px);border-color:rgba(0,212,255,.5);
  box-shadow:0 24px 46px -24px rgba(0,0,0,.85),0 0 34px -10px rgba(0,212,255,.4)}
.pf .ic{width:2.6rem;height:2.6rem;border-radius:12px;
  background:linear-gradient(150deg,rgba(0,212,255,.22),rgba(0,212,255,.05));
  border-color:rgba(0,212,255,.34);
  transition:transform .4s cubic-bezier(.16,1,.3,1)}
.pf:hover .ic{transform:scale(1.09) rotate(-6deg)}
.pf .ic svg{width:1.25rem;height:1.25rem}
.pf h3{font-size:1rem;margin-bottom:.4rem}
.pf p{font-size:.87rem;line-height:1.6}

/* --- 6. Case-study artwork: taller, and the hover is the payoff --- */
.cases{gap:1.5rem}
.cs{border-radius:16px;transition:transform .4s cubic-bezier(.16,1,.3,1),box-shadow .4s ease,border-color .3s ease}
.cs .art{height:9.75rem}
.cs .bd{padding:1.5rem 1.5rem 1.4rem;gap:.6rem}
.cs p{font-size:.9rem;line-height:1.62}
.cs:hover{transform:translateY(-8px);border-color:#AFCFE4;
  box-shadow:0 34px 58px -26px rgba(0,74,119,.55)}
.cs .veil{background:linear-gradient(155deg,rgba(0,212,255,.4) 0%,rgba(0,48,88,.92) 100%)}
.cs .scan{box-shadow:0 0 16px 2px var(--cy)}
.cs .over{font-size:.66rem;letter-spacing:.16em}
@keyframes scanline{0%{opacity:0;transform:translateY(0)}14%{opacity:1}100%{opacity:0;transform:translateY(9.75rem)}}

/* --- 7. Compliance and contact get the same air --- */
.frames{gap:1.4rem}
.fr{padding:1.75rem 1.6rem;border-radius:14px}
.fr h3{font-size:1.3rem;margin-bottom:.65rem}
.fr > p{font-size:.9rem;line-height:1.62}
.panel{padding:clamp(2.2rem,4.5vw,4rem);border-radius:20px}
.dash{border-radius:14px}

@media (prefers-reduced-motion:reduce){
  .v-row{gap:1.6rem 2.6rem}
}

/* ==========================================================================
   v7.1 — TYPOGRAPHY, COPY WEIGHT AND CONTRAST
   No layout concept changes. This pass raises reading size and text
   authority, and fixes one real contrast bug in the contact panel.
   ========================================================================== */

/* --- 1. Base reading size 16 -> 17px, and darker body ink on paper --- */
:root{--on-paper-dim:#3D5468;--on-dark-dim:#A9BFD3}
body{font-size:1.0625rem;line-height:1.65}
h2{font-size:clamp(2.05rem,3.9vw,3.4rem)}
.lede{font-weight:450}
.intro-top .lede{font-size:1.19rem;line-height:1.62}
.proof-head .lede{font-size:1.15rem}

/* --- 2. Service cards: bigger heading, bigger body, more padding ---
   Descriptive copy sits at weight 450 — Inter is variable, so this is a real
   weight, not a synthetic one, and it stops body text reading as thin. */
.cards{gap:1.75rem}
.cd{padding:2.1rem 1.9rem 1.8rem;gap:.75rem}
.cd .ic{width:3.1rem;height:3.1rem}
.cd .ic svg{width:1.45rem;height:1.45rem}
.cd h3{font-size:1.28rem;line-height:1.3;font-weight:700}
.cd p{font-size:1.04rem;line-height:1.58;font-weight:450;color:var(--on-paper-dim)}
.cd .go{font-size:.95rem;font-weight:500;padding-top:1.15rem}
.cd-wide .cd-body p{font-size:1.04rem}

/* --- 3. NFTBan feature cards, case studies, compliance --- */
.pf h3{font-size:1.12rem}
.pf p{font-size:.97rem;line-height:1.58;font-weight:450;color:var(--on-dark-dim)}
.cases{gap:1.75rem}
.cs h3{font-size:1.18rem}
.cs p{font-size:1rem;line-height:1.58;font-weight:450;color:var(--on-paper-dim)}
.cs .bd{padding:1.6rem 1.6rem 1.5rem}
.frames{gap:1.6rem}
.fr{padding:1.95rem 1.8rem}
.fr h3{font-size:1.42rem}
.fr > p{font-size:1rem;line-height:1.6;font-weight:450}
.fr li{font-size:.95rem;line-height:1.56}
.fr .scope{font-size:.85rem;line-height:1.55}
.note,.ind{font-size:.95rem;line-height:1.6}

/* --- 4. Contact panel — this was a genuine bug, not just a weak style.
   `.btn-line` carries the LIGHT-theme colours (`--on-paper` #0A1826 on a
   transparent fill). Inside the dark contact panel that put near-black text
   on a #122A47 ground at roughly 1.2:1 — the phone number was effectively
   invisible, which is why it read as disabled. It now gets its own dark-ground
   treatment. Values are also brighter than their labels. --- */
.panel .lede{font-size:1.15rem;font-weight:450;color:var(--on-dark-dim)}
.panel .btn-line{border-color:rgba(0,212,255,.55);color:#9EEBFF;
  background:rgba(0,212,255,.08);font-weight:600}
.panel .btn-line:hover{background:rgba(0,212,255,.18);border-color:var(--cy);color:#fff;
  transform:translateY(-2px)}
.panel .note-fine{margin-top:1.15rem;font-size:.92rem;color:var(--on-dark-faint)}
.info{gap:1.25rem}
.info dt{font-size:.67rem;letter-spacing:.16em;color:var(--on-dark-faint)}
.info dd{font-size:1.06rem;font-weight:500;color:#fff}
.info a{color:#fff;border-bottom-color:rgba(255,255,255,.28)}
.info a:hover{color:var(--cy);border-bottom-color:var(--cy)}

/* --- 5. Vendor marquee: marks up ~15%, more air, slower, Linux as a wordmark
   set in the page's own display face rather than a mark that will not render --- */
.v-row{gap:clamp(3.8rem,7.2vw,6.4rem);padding:0 clamp(3.8rem,7.2vw,6.4rem) 0 0;animation-duration:74s}
/* glyphs honour --s: line-art marks need more height than solid wordmarks to
   carry the same optical weight */
.v-glyph .v-mark{height:calc(2.8rem * var(--s,1))}
.v-word .v-mark{height:1.55rem}

/* ==========================================================================
   v8 — multi-page additions.
   Everything below is new surface introduced by the GRC release. The tokens,
   buttons, cards, frames and marquee above are unchanged from v7.1, so the
   new pages are visibly the same site.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Type rendering. Commissioner and Inter are both variable and both carry a
   real Greek design (Commissioner's Greek is drawn, not interpolated from the
   Latin). Three rules keep that quality on screen:
     font-synthesis:none  — never let the browser fake a bold or an italic;
                            a synthesised Greek bold smears the tonos.
     text-rendering       — keep kerning and ligatures on for body text.
     optical sizing       — headings get the display cut, body the text cut.
   -------------------------------------------------------------------------- */
html{font-synthesis-weight:none;font-synthesis-style:none;text-rendering:optimizeLegibility}
body{-moz-osx-font-smoothing:grayscale;font-optical-sizing:auto;
  font-variant-numeric:proportional-nums;font-feature-settings:"kern" 1,"liga" 1,"calt" 1}
/* Tabular figures wherever numbers are compared down a column, so the digits
   line up: phone numbers, article numbers, deadlines, spec tables. */
.mono,.kv dd,.steps li::before,.law .pill,.info dd{font-variant-numeric:tabular-nums}
h1,h2,h3,h4,.h-disp{font-optical-sizing:auto}
/* Greek needs a touch more line-height than Latin at the same size — the
   descenders (β, γ, η, μ, ρ, φ, χ, ψ) reach further than Latin's do. */
:lang(el) p,:lang(el) li{line-height:1.7}

/* --------------------------------------------------------------------------
   Page hero — the compact version of the homepage hero, for inner pages.
   -------------------------------------------------------------------------- */
.phero{background:var(--ink);color:var(--on-dark);padding:clamp(2.6rem,6vw,4.6rem) 0 clamp(2.8rem,6vw,4.4rem);
  border-bottom:1px solid var(--rule);position:relative;overflow:hidden}
.phero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(60rem 22rem at 78% -10%,rgba(0,212,255,.10),transparent 62%)}
.phero>*{position:relative;z-index:1}
.phero h1{max-width:22ch;margin:.85rem 0 0}
.phero .lede{max-width:44rem;margin-top:1.15rem;font-size:clamp(1.05rem,1.5vw,1.22rem);color:var(--on-dark-dim)}
.phero .cta-row{margin-top:1.9rem}

.crumb{font-size:.78rem;color:var(--on-dark-faint)}
.crumb ol{list-style:none;display:flex;flex-wrap:wrap;gap:.5rem;margin:0;padding:0}
.crumb li::after{content:"/";margin-left:.5rem;opacity:.5}
.crumb li:last-child::after{content:none}
.crumb a{color:var(--on-dark-dim);text-decoration:none}
.crumb a:hover{color:var(--cy)}
.crumb [aria-current]{color:var(--on-dark)}

/* --------------------------------------------------------------------------
   The GRC loop. This is the one diagram on the site that argues rather than
   decorates: the three pillars are drawn as arcs of ONE closed ring, because
   the point of GRC is that the three feed each other. Governance writes the
   rule, risk measures the distance from it, compliance proves the distance
   was closed, and the finding goes back to governance.

   A single bright segment travels the ring forever — you cannot look at it
   and think the three are separate services you buy one of.

   It is an <svg> with real <text>, so it survives no-JS, zooms cleanly, and
   is read out in order by a screen reader. Motion is pure CSS dashoffset and
   stops dead under prefers-reduced-motion, where the ring stays fully drawn.
   -------------------------------------------------------------------------- */
.loop{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:clamp(2rem,5vw,4.5rem);align-items:center}
.loop-fig{margin:0;position:relative}
.loop-fig svg{width:100%;height:auto;display:block;overflow:visible}
.loop-ring{fill:none;stroke-width:10;stroke-linecap:round}
.loop-g{stroke:var(--cy)}
.loop-r{stroke:var(--warn)}
.loop-c{stroke:var(--ok)}
.loop-track{fill:none;stroke:var(--rule-lit);stroke-width:1.5;opacity:.7}
.loop-pulse{fill:none;stroke:#FFFFFF;stroke-width:10;stroke-linecap:round;
  stroke-dasharray:26 627.5;stroke-dashoffset:0;filter:drop-shadow(0 0 6px rgba(255,255,255,.55));
  animation:loop-run 9s linear infinite}
@keyframes loop-run{to{stroke-dashoffset:-653.5}}
.loop-lbl{font-family:Commissioner,Inter,sans-serif;font-weight:700;font-size:15px;letter-spacing:-.01em;fill:var(--on-dark)}
.loop-sub{font-family:"JetBrains Mono",monospace;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase}
.loop-sub-g{fill:var(--cy)}.loop-sub-r{fill:var(--warn)}.loop-sub-c{fill:var(--ok)}
.loop-core{font-family:Commissioner,Inter,sans-serif;font-weight:800;font-size:30px;fill:var(--on-dark);letter-spacing:.02em}
.loop-core-s{font-family:"JetBrains Mono",monospace;font-size:8.5px;letter-spacing:.2em;fill:var(--on-dark-faint)}
.loop-arrow{fill:var(--rule-lit)}

.loop-keys{list-style:none;margin:0;padding:0;display:grid;gap:1.15rem}
.loop-keys li{display:grid;grid-template-columns:auto minmax(0,1fr);gap:1rem;align-items:start;
  padding-bottom:1.15rem;border-bottom:1px solid var(--rule)}
.loop-keys li:last-child{border-bottom:0;padding-bottom:0}
.loop-keys .dot{width:.7rem;height:.7rem;border-radius:50%;margin-top:.42rem;flex:none}
.loop-keys .dot-g{background:var(--cy)}
.loop-keys .dot-r{background:var(--warn)}
.loop-keys .dot-c{background:var(--ok)}
.loop-keys h3{font-size:1.16rem;font-weight:700;margin-bottom:.3rem;color:var(--on-dark)}
.loop-keys h3 .en{font-family:"JetBrains Mono",monospace;font-size:.66rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--on-dark-faint);margin-left:.6rem;font-weight:500}
.loop-keys p{color:var(--on-dark-dim);font-size:1rem}
@media (max-width:56rem){
  .loop{grid-template-columns:1fr;gap:2.4rem}
  .loop-fig{max-width:26rem;margin-inline:auto}
}

/* --------------------------------------------------------------------------
   Pillar cards, spec rows, process steps
   -------------------------------------------------------------------------- */
.pill3{display:grid;grid-template-columns:repeat(auto-fit,minmax(17rem,1fr));gap:1.4rem}
.pill3 .cd{display:flex;flex-direction:column}
.pill3 .cd .go{margin-top:auto;padding-top:1.15rem}

/* Each <div> here is one row holding a dt and a dd. Putting the two-column
   track on the <dl> made every <div> a single cell instead, so rows landed
   side by side — label above text, then the next label squeezed into the right
   column. The tracks belong on the row, and subgrid keeps the label column the
   same width down the list. */
.kv{margin:0;display:grid;grid-template-columns:minmax(9rem,13rem) minmax(0,1fr);gap:0}
.kv>div{display:grid;grid-column:1/-1;grid-template-columns:12rem minmax(0,1fr)}
@supports (grid-template-columns:subgrid){
  .kv>div{grid-template-columns:subgrid}
}
.kv dt{font-family:"JetBrains Mono",monospace;font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--on-paper-dim);padding:.95rem 1.2rem .95rem 0;border-top:1px solid var(--edge)}
.kv dd{margin:0;padding:.95rem 0;border-top:1px solid var(--edge);font-size:1rem;color:var(--on-paper)}
.kv>div:first-child dt,.kv>div:first-child dd{border-top:0}
.dark .kv dt{color:var(--on-dark-faint);border-color:var(--rule)}
.dark .kv dd{color:var(--on-dark);border-color:var(--rule)}
@media (max-width:34rem){
  .kv{grid-template-columns:1fr}
  .kv dd{padding-top:0;border-top:0}
  .kv dt{padding-bottom:.3rem}
}

.steps{list-style:none;counter-reset:s;margin:0;padding:0;display:grid;gap:1.6rem}
.steps li{counter-increment:s;display:grid;grid-template-columns:auto minmax(0,1fr);gap:1.25rem;align-items:start}
.steps li::before{content:counter(s,decimal-leading-zero);font-family:"JetBrains Mono",monospace;
  font-size:.82rem;font-weight:600;color:var(--cy-deep);border:1px solid var(--edge-2);border-radius:50%;
  width:2.5rem;height:2.5rem;display:grid;place-items:center;flex:none;background:var(--card)}
.dark .steps li::before{color:var(--cy);border-color:var(--rule-lit);background:var(--ink-2)}
.steps h3{font-size:1.1rem;font-weight:700;margin-bottom:.35rem}
.steps p{color:var(--on-paper-dim)}
.dark .steps p{color:var(--on-dark-dim)}
@media (min-width:52rem){.steps{grid-template-columns:1fr 1fr;gap:2.2rem 3rem}}

/* --------------------------------------------------------------------------
   FAQ. <details> so it works with JavaScript switched off, and so the answer
   text is in the DOM for a search engine to read even while collapsed.
   -------------------------------------------------------------------------- */
.faq{display:grid;gap:0;max-width:52rem}
.faq details{border-top:1px solid var(--edge)}
.faq details:last-of-type{border-bottom:1px solid var(--edge)}
.faq summary{list-style:none;cursor:pointer;padding:1.35rem 2.6rem 1.35rem 0;position:relative;
  font-family:Commissioner,Inter,sans-serif;font-weight:650;font-size:1.06rem;letter-spacing:-.012em;
  color:var(--on-paper);line-height:1.4}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:.4rem;top:1.75rem;width:.72rem;height:.72rem;
  border-right:2px solid var(--cy-deep);border-bottom:2px solid var(--cy-deep);
  transform:rotate(45deg);transition:transform .2s}
.faq details[open] summary::after{transform:rotate(-135deg)}
.faq summary:hover{color:var(--cy-deep)}
.faq .ans{padding:0 2.6rem 1.5rem 0;color:var(--on-paper-dim);font-size:1rem;max-width:46rem}
.faq .ans p+p{margin-top:.85rem}
.dark .faq details{border-color:var(--rule)}
.dark .faq summary{color:var(--on-dark)}
.dark .faq summary::after{border-color:var(--cy)}
.dark .faq .ans{color:var(--on-dark-dim)}

/* --------------------------------------------------------------------------
   Service rows — the retained web/hosting business. Deliberately quieter than
   the GRC cards: a list with rules, not six more boxes competing for the eye.
   -------------------------------------------------------------------------- */
.svc{display:grid;gap:0;margin:0;padding:0;list-style:none}
.svc>li{display:grid;grid-template-columns:minmax(0,15rem) minmax(0,1fr);gap:clamp(1rem,4vw,3rem);
  padding:1.9rem 0;border-top:1px solid var(--edge)}
.svc>li:last-child{border-bottom:1px solid var(--edge)}
.svc h3{font-size:1.24rem;font-weight:750;letter-spacing:-.02em}
.svc .en{display:block;font-family:"JetBrains Mono",monospace;font-size:.68rem;letter-spacing:.15em;
  text-transform:uppercase;color:var(--on-paper-dim);margin-top:.4rem;font-weight:500}
.svc p{color:var(--on-paper-dim)}
.svc ul{margin:.9rem 0 0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:.45rem}
.svc ul li{font-family:"JetBrains Mono",monospace;font-size:.7rem;letter-spacing:.06em;color:var(--on-paper-dim);
  border:1px solid var(--edge-2);border-radius:99px;padding:.3rem .7rem;background:var(--card)}
@media (max-width:44rem){.svc>li{grid-template-columns:1fr;gap:.9rem}}

/* Registrar badge — a fact with a registry number, not a marketing sticker. */
.reg{display:inline-grid;grid-template-columns:auto minmax(0,1fr);gap:.9rem;align-items:center;
  border:1px solid var(--edge-2);border-left:3px solid var(--cy-deep);border-radius:var(--r-sm);
  background:var(--card);padding:.95rem 1.25rem;margin-top:1.5rem;max-width:34rem}
.reg svg{width:1.5rem;height:1.5rem;stroke:var(--cy-deep);stroke-width:1.7;fill:none}
.reg b{display:block;font-family:Commissioner,Inter,sans-serif;font-size:.98rem;letter-spacing:-.01em}
.reg span{font-family:"JetBrains Mono",monospace;font-size:.74rem;color:var(--on-paper-dim);letter-spacing:.05em}

/* --------------------------------------------------------------------------
   Honest callout, related links, closing band
   -------------------------------------------------------------------------- */
.callout{border-left:3px solid var(--warn);background:#FFF9F1;padding:1.3rem 1.5rem;border-radius:0 var(--r-sm) var(--r-sm) 0;
  max-width:48rem;color:#5C3A0C;font-size:.98rem}
.callout b{color:#4A2E06}
.dark .callout{background:rgba(240,168,92,.09);border-left-color:var(--warn);color:var(--on-dark-dim)}
.dark .callout b{color:var(--warn)}

.rel{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1rem;margin-top:2.6rem}
.rel a{display:block;text-decoration:none;border:1px solid var(--edge);border-radius:var(--r);
  background:var(--card);padding:1.15rem 1.3rem;transition:border-color .18s,transform .18s}
.rel a:hover{border-color:var(--cy-deep);transform:translateY(-2px)}
.rel .k{font-family:"JetBrains Mono",monospace;font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-paper-dim);display:block;margin-bottom:.42rem}
.rel .t{font-family:Commissioner,Inter,sans-serif;font-weight:700;color:var(--on-paper);font-size:1.02rem;letter-spacing:-.015em}
.dark .rel a{background:var(--ink-2);border-color:var(--rule)}
.dark .rel a:hover{border-color:var(--cy)}
.dark .rel .k{color:var(--on-dark-faint)}
.dark .rel .t{color:var(--on-dark)}

.band{background:var(--ink-2);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.band .wrap{padding-block:clamp(2.8rem,6vw,4.4rem)}
.band h2{max-width:20ch}
.band .lede{color:var(--on-dark-dim);max-width:40rem}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.foot{background:var(--ink);color:var(--on-dark-dim);padding:clamp(3rem,6vw,4.6rem) 0 2.2rem;border-top:1px solid var(--rule)}
.foot-grid{display:grid;grid-template-columns:minmax(0,1.5fr) repeat(3,minmax(0,1fr));gap:2.4rem clamp(1.5rem,3vw,3rem)}
.foot-brand{--logo-ring:#8FA6BC;--logo-word:#EAF1F8}
.foot-brand .logo-full{display:block;height:2.3rem;margin-bottom:1.15rem}
.foot-brand .logo-full svg{height:100%;width:auto}
.foot-brand p{font-size:.92rem;max-width:26rem}
.foot-oss{margin-top:1.1rem!important;font-family:"JetBrains Mono",monospace;font-size:.74rem;
  letter-spacing:.04em;color:var(--on-dark-faint)}
.foot-oss a{color:var(--cy);text-decoration:none}
.foot-oss a:hover{text-decoration:underline}
.foot-col h2{font-family:"JetBrains Mono",monospace;font-size:.7rem;font-weight:600;letter-spacing:.17em;
  text-transform:uppercase;color:var(--on-dark);margin-bottom:1rem}
.foot-col ul{list-style:none;margin:0;padding:0;display:grid;gap:.62rem}
.foot-col a{color:var(--on-dark-dim);text-decoration:none;font-size:.92rem}
.foot-col a:hover{color:var(--cy)}
.foot-contact .btn{margin-top:1.25rem}
.foot-legal{margin-top:clamp(2.4rem,5vw,3.4rem);padding-top:1.6rem;border-top:1px solid var(--rule);
  display:grid;gap:.6rem;font-size:.8rem;color:var(--on-dark-faint)}
.foot-legal a{color:var(--on-dark-dim);text-decoration:none}
.foot-legal a:hover{color:var(--cy)}
.foot-note{max-width:60rem;line-height:1.6}
@media (max-width:60rem){.foot-grid{grid-template-columns:1fr 1fr}.foot-brand{grid-column:1/-1}}
@media (max-width:34rem){.foot-grid{grid-template-columns:1fr}}

/* --------------------------------------------------------------------------
   Reduced motion — the ring stops with the whole loop drawn, not mid-gap.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .loop-pulse{animation:none;stroke-dasharray:none;opacity:0}
  html{scroll-behavior:auto}
}

/* Framework cards get the same "read on" affordance the service cards have. */
.fr .go{display:inline-flex;align-items:center;gap:.45rem;margin-top:1.1rem;font-size:.86rem;font-weight:550;
  text-decoration:none;color:var(--cy-deep);letter-spacing:-.005em}
.fr .go:hover{color:var(--navy)}
.fr{display:flex;flex-direction:column}
.fr .law{margin-top:auto}

/* ==========================================================================
   v8 PREMIUM PASS
   --------------------------------------------------------------------------
   The brief: expensive, elegant, focused — and not classic.

   In this category "expensive" is not more effects. Every competitor in Greek
   cybersecurity already ships gradients, glows and stock padlocks; that look
   is the cheap one now. Expensive here is drafting-room precision: a lot of
   air, a type scale with real jumps in it, hairlines that land on a datum,
   and exactly one moment of motion per page.

   So this pass spends its budget on four things and nothing else:
     1. a wider type scale (display much larger, labels much smaller)
     2. much more vertical air on desktop — and deliberately less on phones,
        because the mobile page was measured at 15,391px and that is a defect
     3. a datum rule: every section eyebrow is tied to the page's left margin
     4. a faint drafted grid on dark ground — this firm writes rule chains,
        so the site should look drawn to spec rather than decorated
   ========================================================================== */

:root{
  /* Air. Small on a phone, generous on a desk — one token, both jobs. */
  --gap:clamp(3.6rem,8.5vw,9rem);
  --gap-s:clamp(2.4rem,5vw,4.5rem);

  /* Hairlines. A drafted line is not a border; it is thinner and cooler. */
  --wire:rgba(0,212,255,.16);
  --wire-faint:rgba(0,212,255,.055);
  --datum:rgba(255,255,255,.10);

  --r:12px;--r-sm:7px;
}

/* --------------------------------------------------------------------------
   1. Type scale. The jumps are deliberately wide: 5rem display against a
   .68rem label, with nothing hedging in the middle. Even steps read as a
   theme; uneven steps read as a decision.
   -------------------------------------------------------------------------- */
h1{font-size:clamp(2.35rem,5.6vw,4.6rem);letter-spacing:-.038em;line-height:1.03;font-weight:800}
h2{font-size:clamp(1.85rem,3.6vw,3.05rem);letter-spacing:-.032em;line-height:1.08}
h3{font-size:1.22rem;letter-spacing:-.018em;font-weight:700;line-height:1.3}

/* No orphans, no widows, no ragged headline. This one property is most of the
   difference between a page that looks set and a page that looks poured. */
h1,h2,h3,h4,.lede,.loop-keys h3,.steps h3{text-wrap:balance}
p,li,.ans,dd{text-wrap:pretty}

body{font-size:1.06rem;line-height:1.66}
.lede{font-size:clamp(1.06rem,1.5vw,1.3rem);line-height:1.55;color:var(--on-paper-dim);max-width:46ch;font-weight:420}
.dark .lede{color:var(--on-dark-dim)}
p{max-width:68ch}

/* The utility voice: specification labels, not decoration. Tighter, smaller
   and further apart than a normal caption, so it reads as machine-set. */
.tag,.foot-col h2,.svc .en,.rel .k,.loop-keys h3 .en,.kv dt,.loop-sub{
  font-size:.68rem;letter-spacing:.2em;font-weight:500}

/* --------------------------------------------------------------------------
   2. The datum. Every section eyebrow now sits on a hairline that runs to the
   left edge of the container and stops — the way a dimension line stops on a
   drawing. It replaces the old floating dash, which pointed at nothing.
   -------------------------------------------------------------------------- */
.tag{position:relative;padding-bottom:1.1rem;margin-bottom:.2rem;display:block}
.tag::before{content:none}
.tag::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;
  background:linear-gradient(90deg,currentColor 0 3.2rem,var(--datum) 3.2rem 100%);opacity:.85}
.sec:not(.dark) .tag::after{background:linear-gradient(90deg,currentColor 0 3.2rem,var(--edge) 3.2rem 100%)}
/* The eyebrow's own rule should not run the width of a wide page — it marks a
   column, not the whole spread. */
.intro .tag::after,.phero .tag::after{max-width:26rem}

/* --------------------------------------------------------------------------
   3. Drafted ground. A 1px column grid at ~3% on dark sections only. It is
   below the threshold where you would call it a pattern; you register it as
   texture and read the page as drawn. Off on phones, where it only costs
   paint time and shows as banding.
   -------------------------------------------------------------------------- */
@media (min-width:60rem){
  .dark,.band{position:relative}
  .dark::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
    background-image:repeating-linear-gradient(90deg,var(--wire-faint) 0 1px,transparent 1px 8.3333%);
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 12%,#000 88%,transparent);
    mask-image:linear-gradient(180deg,transparent,#000 12%,#000 88%,transparent)}
  /* Lift only the content wrapper above the grid. An earlier version raised
     every child of .dark, which matched .hero-fx too — same specificity as
     .hero-fx{position:absolute} but written later, so the hero's canvas host
     fell back into flow and stretched the hero past 1800px. Touch the wrap,
     nothing else. */
  .dark>.wrap{position:relative;z-index:1}
}

/* --------------------------------------------------------------------------
   4. Surfaces. Cards lose their heavy border and gain a hairline plus a real
   shadow — the difference between a box and a printed card.
   -------------------------------------------------------------------------- */
.cd,.fr,.rel a,.reg{border-color:var(--edge);
  box-shadow:0 1px 2px rgba(8,21,34,.04),0 8px 26px -18px rgba(8,21,34,.30)}
.cd:hover,.fr:hover{box-shadow:0 1px 2px rgba(8,21,34,.05),0 20px 44px -26px rgba(8,21,34,.42)}
.dark .cd,.dark .fr,.dark .rel a{box-shadow:none;background:linear-gradient(180deg,var(--ink-2),var(--ink))}

/* Buttons: taller, calmer, with the fill lifted off the ground. A CTA that
   looks like it costs money does not bounce. */
.btn{padding:1rem 1.6rem;font-size:.92rem;font-weight:520;letter-spacing:-.005em;border-radius:var(--r-sm)}
.btn-fill{box-shadow:0 10px 24px -14px rgba(0,74,119,.75)}
.dark .btn-fill{box-shadow:0 12px 30px -14px rgba(0,212,255,.55)}
.btn-fill:hover{transform:translateY(-1px)}
.cta-row{display:flex;flex-wrap:wrap;gap:.85rem;align-items:center}

/* --------------------------------------------------------------------------
   5. Panels get an inner hairline instead of a border — the "matted print"
   effect. Cheap to draw, and it is the single detail that most separates an
   expensive layout from a bootstrapped one.
   -------------------------------------------------------------------------- */
.panel,.dash{box-shadow:inset 0 0 0 1px var(--wire),0 40px 80px -50px rgba(0,0,0,.9)}

/* --------------------------------------------------------------------------
   6. Focus, always visible, always on brand.
   -------------------------------------------------------------------------- */
:where(a,button,summary,[tabindex]):focus-visible{outline:2px solid var(--cy);outline-offset:3px}

/* --------------------------------------------------------------------------
   7. Mobile length. The v7.1 page measured 15,391px on a 390px viewport.
   Tightening the rhythm rather than deleting content is the honest fix.
   -------------------------------------------------------------------------- */
@media (max-width:46rem){
  .sec{padding:var(--gap) 0}
  .intro{margin-bottom:1.9rem!important}
  .pill3,.frames{gap:1rem}
  h1{font-size:clamp(2rem,8.4vw,2.6rem)}
  .lede{font-size:1.04rem}
}

/* --------------------------------------------------------------------------
   8. The rotating headline.
   The alternates live in the DOM as real text inside .h1-pool so they cost
   nothing to read and nothing to parse; the element is [hidden] and
   aria-hidden, and script lifts the strings out of it. With script off, the
   pool never renders and the <h1> that shipped in the HTML is the headline.
   -------------------------------------------------------------------------- */
.h1-pool{display:none}
.hero .tag{transition:opacity .26s ease,transform .26s ease}
.hero .tag.swap{opacity:0;transform:translateY(-4px)}
/* Reserve the tallest statement's height so the CTA row never jumps when the
   line count changes. A layout that shifts under motion reads as broken. */
.hero h1{min-height:calc(2 * 1.03em)}

/* --------------------------------------------------------------------------
   9. Fixes found by rendering, not by reading.
   -------------------------------------------------------------------------- */
/* "Προστατευμένο" is a long word in a narrow flex child that could not shrink,
   so it printed over its own border. A flex item needs min-width:0 before it is
   allowed to wrap — this is the default nobody expects. */
.status>span{min-width:0}
.status b{overflow-wrap:break-word}

/* The policy-set list is revealed by script. If site.js fails to load while
   JavaScript is otherwise on, .up never arrives and the list stays invisible —
   the same failure the headline already guards against. Same guard, same idea:
   a missed animation is acceptable, a blank panel is not. */
.js .sets li{animation:failsafe 0s linear 2.5s forwards}

/* The page hero is a dark context, so it must be marked as one. Before it was,
   .btn-line kept its light-theme label colour and measured 1.03:1 against the
   hero ground — an invisible button, not a dim one — and the eyebrow sat at
   2.87:1. Both are inherited correctly now that .phero carries .dark. */
.phero{background:var(--ink)}
.crumb{margin-bottom:1.6rem}

/* --------------------------------------------------------------------------
   10. External destinations in the footer. Three real places a visitor may
   want to go — the source, the product site, the client area — each labelled
   with what it is rather than an unexplained icon.
   -------------------------------------------------------------------------- */
.foot-links-ext{list-style:none;margin:1.4rem 0 0;padding:0;display:grid;gap:.55rem;max-width:26rem}
.foot-links-ext a{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:1rem;
  text-decoration:none;padding:.62rem .9rem;border:1px solid var(--rule);border-radius:var(--r-sm);
  background:var(--ink-2);transition:border-color .18s,transform .18s}
.foot-links-ext a:hover{border-color:var(--cy);transform:translateX(2px)}
.foot-links-ext .l{font-family:"JetBrains Mono",monospace;font-size:.78rem;color:var(--cy);letter-spacing:.02em;
  overflow-wrap:anywhere}
.foot-links-ext .s{font-size:.74rem;color:var(--on-dark-faint);white-space:nowrap}

/* --------------------------------------------------------------------------
   11. Mobile length, second pass.
   v7.1's homepage measured 15,391px at 390px wide. The rhythm work above took
   v8 to 11,736px; these three cuts remove what a phone reader gains least from,
   without removing anything a desktop reader sees.
   -------------------------------------------------------------------------- */
@media (max-width:46rem){
  :root{--gap:clamp(3rem,8vw,9rem)}
  /* The event feed makes its point in four rows. Rows five and six are the same
     point again, at 78px each. */
  .feed li:nth-child(n+5){display:none}
  /* The footer's four columns become four stacked lists; the link rows are the
     tallest part of it and read fine at a tighter step. */
  .foot-col ul{gap:.45rem}
  .foot-links-ext{gap:.4rem}
  .foot-links-ext a{padding:.5rem .75rem}
  /* Card padding is generous by design on a desk; on a phone it is just scroll. */
  .cd,.fr{padding:1.25rem 1.25rem 1.35rem}
  .svc>li{padding:1.5rem 0}
}

/* --------------------------------------------------------------------------
   12. Inner-page heroes get a right-hand column.
   The page heroes shipped as text with an empty half beside it, which read as
   an unfinished layout next to the homepage's hero. Each inner page now puts
   something true in that space: grc.html puts its ring there, and the rest put
   a specification panel — the facts a reader would otherwise scroll to find.
   -------------------------------------------------------------------------- */
.phero-grid{display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center}
.phero-grid .lede{max-width:38ch}
@media (max-width:62rem){
  .phero-grid{grid-template-columns:1fr;gap:2.6rem}
  .phero-grid .loop-fig{max-width:21rem;margin-inline:auto}
  .phero-grid .lede{max-width:46ch}
}

/* The ring in the hero: a little smaller than it was as a section figure, and
   with the pulse's glow tightened so it does not bloom over the headline. */
.phero-grid .loop-fig{max-width:25rem;margin-inline:auto}

/* Freed from the ring, the three pillars read as a row rather than a list. */
@media (min-width:56rem){
  .loop-keys{grid-template-columns:repeat(3,minmax(0,1fr));gap:2rem}
  .loop-keys li{border-bottom:0;padding-bottom:0;border-top:1px solid var(--rule);
    padding-top:1.3rem;align-content:start}
}

/* --------------------------------------------------------------------------
   The specification panel. Same family as the homepage dashboard — hairline,
   mono labels, ink-2 ground — so the two read as one system.
   -------------------------------------------------------------------------- */
.facts{background:linear-gradient(180deg,var(--ink-2),var(--ink));border-radius:var(--r);
  box-shadow:inset 0 0 0 1px var(--wire),0 40px 80px -50px rgba(0,0,0,.9);
  padding:1.5rem 1.6rem 1.7rem;margin:0}
.facts-h{display:flex;align-items:center;gap:.6rem;font-family:"JetBrains Mono",monospace;
  font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--cy);
  padding-bottom:1rem;margin-bottom:.2rem;border-bottom:1px solid var(--rule)}
.facts-h::before{content:"";width:.42rem;height:.42rem;border-radius:50%;background:var(--cy);flex:none}
.facts dl{margin:0}
.facts>dl>div{display:grid;gap:.2rem;padding:.95rem 0;border-bottom:1px solid var(--rule)}
.facts>dl>div:last-child{border-bottom:0;padding-bottom:0}
.facts dt{font-family:"JetBrains Mono",monospace;font-size:.64rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--on-dark-faint)}
.facts dd{margin:0;font-size:.95rem;line-height:1.5;color:var(--on-dark)}
.facts dd .mono{font-size:.88rem;color:var(--cy)}
@media (max-width:62rem){.facts{max-width:32rem;margin-inline:auto}}

/* The inner-page display is deliberately a step below the homepage's — the
   homepage headline should stay the largest type on the site — and at that
   size it stops breaking "GRC:" onto a line of its own. */
.phero-grid h1{font-size:clamp(2.1rem,3.9vw,3.5rem)}
.phero-grid{grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr)}
.phero-grid .loop-fig{max-width:27rem}
@media (max-width:62rem){.phero-grid{grid-template-columns:1fr}}

/* --------------------------------------------------------------------------
   13. Credentials.
   Grouped by issuer, because "who issued it" is half the claim. The year sits
   in the mono voice on the right so a reader can scan the track record down
   the column instead of reading every line.
   -------------------------------------------------------------------------- */
.creds{display:grid;grid-template-columns:repeat(auto-fit,minmax(19rem,1fr));gap:1.15rem}
.cred-group{border:1px solid var(--edge);border-radius:var(--r);background:var(--card);
  padding:1.3rem 1.4rem 1.1rem;
  box-shadow:0 1px 2px rgba(8,21,34,.04),0 8px 26px -18px rgba(8,21,34,.30)}
.cred-group h3{font-size:.94rem;font-weight:700;letter-spacing:-.01em;color:var(--cy-deep);
  padding-bottom:.8rem;margin-bottom:.3rem;border-bottom:1px solid var(--edge)}
.cred-group ul{list-style:none;margin:0;padding:0}
.cred-group li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.9rem;align-items:baseline;
  padding:.62rem 0;border-bottom:1px solid var(--edge)}
.cred-group li:last-child{border-bottom:0;padding-bottom:0}
.cred-group .n{font-size:.94rem;line-height:1.45;color:var(--on-paper)}
.cred-group .y{font-family:"JetBrains Mono",monospace;font-size:.72rem;color:var(--on-paper-dim);
  font-variant-numeric:tabular-nums}
.dark .cred-group{background:linear-gradient(180deg,var(--ink-2),var(--ink));
  border-color:var(--rule);box-shadow:none}
.dark .cred-group h3{color:var(--cy);border-bottom-color:var(--rule)}
.dark .cred-group li{border-bottom-color:var(--rule)}
.dark .cred-group .n{color:var(--on-dark)}
.dark .cred-group .y{color:var(--on-dark-faint)}

/* An h1 that is a full positioning sentence needs a smaller step than a
   three-word headline, or it fills the hero on its own. */
.h1-long{font-size:clamp(1.5rem,2.3vw,2.05rem);letter-spacing:-.024em;line-height:1.16;max-width:24ch}

/* The service index lives in v81.css now — the old four-column block was
   removed because its grid tracks survived the rewrite and turned four rows
   into four columns with the labels printing over the links. */


/* ==========================================================================
   V8.1 — ART DIRECTION PASS
   --------------------------------------------------------------------------
   V8 was correct and too quiet. It read as component library rather than as a
   firm that engineers infrastructure and ships its own IPS. This file does not
   touch structure, content or the build; it changes how the same HTML looks.

   Loaded last, so it is the whole diff. Delete this file and V8 returns.

   The budget goes to five things, in this order:
     1. a deeper, lit palette — navy that has floors and ceilings, not one flat
        value, with cyan used as illumination rather than as a line colour
     2. a bigger, more confident type scale
     3. surfaces with real depth: layered grounds, inner hairlines, lifted cards
     4. page-specific diagram systems, so no two inner pages compose alike
     5. motion that means scanning, flow and enforcement
   ========================================================================== */

:root{
  /* ---- Ground. Four steps instead of one, so a page can have a floor, a
     surface, a raised panel and a lit edge. --void is below --ink and is what
     makes the lit areas read as lit. ---------------------------------------- */
  --void:#04101B;
  --ink:#071522;
  --ink-2:#0B1E31;
  --ink-3:#122C46;
  --ink-4:#1A3A58;

  --rule:#1B3247;
  --rule-lit:#2C4C6A;
  --wire:rgba(0,212,255,.18);
  --wire-faint:rgba(0,212,255,.06);

  /* ---- Illumination. Cyan is a light source on dark ground, never a text
     colour on paper — it measures 1.77:1 there. -------------------------------*/
  --cy:#00D4FF;
  --cy-lit:#7FE6FF;
  --cy-deep:#0B658F;
  --cy-soft:rgba(0,212,255,.14);
  --glow-cy:0 0 0 1px rgba(0,212,255,.22),0 18px 60px -24px rgba(0,212,255,.55);

  /* ---- Framework identity. Each regulation gets one colour and keeps it on
     every page it appears. Measured on --ink and on white before adoption. --- */
  --fw-nis2:#00D4FF;      --fw-nis2-deep:#0B658F;
  --fw-dora:#B39DFF;      --fw-dora-deep:#5B3FB8;
  --fw-iso:#4FD1A1;       --fw-iso-deep:#0F7355;
  --fw-gdpr:#F0A85C;      --fw-gdpr-deep:#8A5A12;
  --fw-bcm:#7FB4FF;       --fw-bcm-deep:#2B5FA8;   /* ISO 22301 — 8.67:1 / 6.35:1 */

  --block:#F2704F;--warn:#F0A85C;--ok:#4FD1A1;
  --navy:#004A77;--navy-lift:#0A6396;

  /* ---- Paper. Cool, not sterile; cards sit above it rather than merging. --- */
  --paper:#EDF1F6;
  --paper-2:#E4EAF2;
  --card:#FFFFFF;
  --edge:#D5DEE8;
  --edge-2:#B9C7D5;

  --on-dark:#EAF1F8;--on-dark-dim:#A9BFD3;--on-dark-faint:#7590AB;
  --on-paper:#0A1826;--on-paper-dim:#3D5468;

  /* ---- Rhythm. Sections differ on purpose: --gap for a normal band, --gap-lg
     around the ideas that carry the page, --gap-s for repetitive content. ---- */
  --gap:clamp(4.2rem,7.5vw,8rem);
  --gap-lg:clamp(5.5rem,10vw,11rem);
  --gap-s:clamp(2.6rem,5vw,4.5rem);

  --r:14px;--r-sm:9px;--r-lg:20px;

  --lift-1:0 1px 2px rgba(7,21,34,.05),0 10px 30px -18px rgba(7,21,34,.35);
  --lift-2:0 2px 4px rgba(7,21,34,.06),0 28px 56px -28px rgba(7,21,34,.45);
  --lift-dark:0 30px 80px -40px rgba(0,0,0,.95);
}

/* ==========================================================================
   1. TYPE — larger, and weighted toward the display face
   ========================================================================== */
body{font-size:1.125rem;line-height:1.62}          /* 18px */

h1{font-size:clamp(2.6rem,5.4vw,5rem);letter-spacing:-.042em;line-height:1.01;font-weight:800}
h2{font-size:clamp(2rem,3.6vw,3.1rem);letter-spacing:-.034em;line-height:1.06}
h3{font-size:1.3rem;letter-spacing:-.02em;font-weight:700;line-height:1.28}   /* ~21px */

/* Inner pages sit one step below the homepage, which stays the loudest type
   on the site — but 52–64px, not the 34px they were. */
.phero-grid h1{font-size:clamp(2.3rem,4.3vw,4rem);letter-spacing:-.036em;line-height:1.04}
.h1-long{font-size:clamp(1.85rem,2.9vw,2.7rem);letter-spacing:-.028em;line-height:1.14;max-width:26ch}

.lede{font-size:clamp(1.15rem,1.45vw,1.32rem);line-height:1.5;font-weight:400;max-width:48ch}  /* 18.5–21px */
.phero .lede{font-size:clamp(1.18rem,1.55vw,1.38rem)}

.cd p,.fr>p{font-size:1.09rem;line-height:1.56;font-weight:420}   /* ~17.5px */
.cd h3,.fr h3{font-size:1.34rem;font-weight:700;letter-spacing:-.02em}

/* The mono voice is an accent, not the page's texture: fewer things wear it,
   and the ones that do are a shade larger so they stop looking like fine print. */
.tag,.foot-col h2,.idx-col h3,.facts-h{font-size:.73rem;letter-spacing:.19em;font-weight:600}
.kv dt,.facts dt{font-size:.7rem;letter-spacing:.15em}
.kv dd,.facts dd{font-size:1.04rem;line-height:1.52}
.svc .en,.rel .k,.loop-keys h3 .en{font-size:.7rem;letter-spacing:.16em}
.tab-list li,.svc ul li{font-size:.78rem}
.cred-group .n{font-size:1rem}
.faq summary{font-size:1.14rem}
.faq .ans{font-size:1.06rem}
.steps h3{font-size:1.2rem}
.steps p{font-size:1.06rem}

/* ==========================================================================
   2. HEADER — larger mark, more air, an active state you can see
   ========================================================================== */
.bar{background:linear-gradient(180deg,rgba(4,16,27,.94),rgba(7,21,34,.88));
  border-bottom:1px solid var(--rule);backdrop-filter:blur(18px) saturate(1.3)}
.bar-in{min-height:5.6rem;gap:1.75rem}
.brand .logo-full,.brand .logo-mark{height:clamp(2.6rem,3.5vw,3.35rem)}   /* +24% */
.bar nav ul{gap:1.9rem}
.bar nav a{font-size:.95rem;letter-spacing:.01em;padding:.45rem 0;position:relative;
  border-bottom:0;color:var(--on-dark-dim)}
.bar nav a::after{content:"";position:absolute;left:0;right:0;bottom:-.15rem;height:2px;
  background:var(--cy);transform:scaleX(0);transform-origin:left;transition:transform .24s cubic-bezier(.2,.7,.3,1)}
.bar nav a:hover{color:var(--on-dark)}
.bar nav a:hover::after{transform:scaleX(1)}
.bar nav a[aria-current="page"]{color:#fff}
.bar nav a[aria-current="page"]::after{transform:scaleX(1);
  box-shadow:0 0 12px 1px rgba(0,212,255,.7)}
.btn-head{padding:.95rem 1.6rem;font-size:.95rem}
.dark .btn-fill,.bar .btn-fill{background:linear-gradient(180deg,#12B7E8,#0895C8);color:#02202D;
  box-shadow:0 1px 0 rgba(255,255,255,.28) inset,0 14px 34px -14px rgba(0,212,255,.75)}
.dark .btn-fill:hover,.bar .btn-fill:hover{background:linear-gradient(180deg,#3ECBF5,#12A6D8);
  box-shadow:0 1px 0 rgba(255,255,255,.35) inset,0 18px 42px -14px rgba(0,212,255,.95)}
@media (max-width:64rem){.bar-in{min-height:4.9rem}}

/* ==========================================================================
   3. GROUND — dark sections stop being one flat navy
   --------------------------------------------------------------------------
   Two layers on every dark band: a vertical fall from --ink to --void, and one
   off-centre cyan radial that acts as a light source. The fall is what makes a
   section feel like a space rather than a swatch; the radial is what makes the
   cyan read as illumination instead of as a border colour.
   ========================================================================== */
.dark,.phero,.band{
  background:
    radial-gradient(72rem 36rem at 84% -12%, rgba(0,212,255,.105), transparent 62%),
    radial-gradient(52rem 30rem at 8% 108%, rgba(0,74,119,.30), transparent 66%),
    linear-gradient(180deg, var(--ink) 0%, var(--void) 100%);
}
/* The closing band is the deepest surface on the page, so the CTA on it reads
   as the last thing standing. */
.band{
  background:
    radial-gradient(60rem 30rem at 78% 120%, rgba(0,212,255,.14), transparent 60%),
    linear-gradient(180deg, var(--void) 0%, #030B14 100%);
}

/* The seam between a dark and a light band is where a page usually looks
   assembled. A hairline plus a short cyan bloom makes it look intentional. */
.dark::after,.phero::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--wire) 18%,var(--wire) 82%,transparent);
  pointer-events:none;z-index:2}
.dark,.phero{position:relative}

/* Light sections get a cool tonal drift instead of one sterile fill, and every
   other one steps a shade deeper so the page has a beat. */
.sec:not(.dark){background:linear-gradient(180deg,#F6F9FC 0%,var(--paper) 46%,var(--paper-2) 100%)}
.sec:not(.dark)+.sec:not(.dark){background:linear-gradient(180deg,var(--paper-2) 0%,var(--paper) 40%,#F6F9FC 100%)}

/* The technical grid stays, but it is drawn on the light side too now — very
   faint, and only on wide screens where it registers as drafting rather than
   as banding. */
@media (min-width:60rem){
  .sec:not(.dark)::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
    background-image:repeating-linear-gradient(90deg,rgba(11,101,143,.045) 0 1px,transparent 1px 8.3333%);
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 14%,#000 86%,transparent);
    mask-image:linear-gradient(180deg,transparent,#000 14%,#000 86%,transparent)}
  .sec:not(.dark){position:relative}
  .sec:not(.dark)>.wrap{position:relative;z-index:1}
}

/* ==========================================================================
   4. SURFACES — cards that sit above the page instead of in it
   ========================================================================== */
.cd,.fr,.cred-group,.rel a,.reg,.tab-list li{border-radius:var(--r)}
.cd,.fr,.cred-group{background:linear-gradient(180deg,#FFFFFF,#FAFCFE);
  border:1px solid var(--edge);box-shadow:var(--lift-1);
  padding:1.7rem 1.7rem 1.8rem;
  transition:transform .26s cubic-bezier(.2,.7,.3,1),box-shadow .26s,border-color .26s}
.cd:hover,.fr:hover,.cred-group:hover{transform:translateY(-3px);box-shadow:var(--lift-2);
  border-color:var(--edge-2)}

.dark .cd,.dark .fr,.dark .cred-group,.dark .rel a{
  background:linear-gradient(180deg,var(--ink-3) 0%,var(--ink-2) 58%,var(--ink) 100%);
  border:1px solid var(--rule);box-shadow:inset 0 1px 0 rgba(255,255,255,.045)}
.dark .cd:hover,.dark .fr:hover,.dark .cred-group:hover,.dark .rel a:hover{
  border-color:var(--rule-lit);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 26px 60px -30px rgba(0,212,255,.35)}

/* Panels get the matted-print inner hairline plus a lit top edge. */
.panel,.dash,.facts{border-radius:var(--r-lg);
  box-shadow:inset 0 0 0 1px var(--wire),inset 0 1px 0 rgba(255,255,255,.08),var(--lift-dark)}
.facts{background:linear-gradient(165deg,var(--ink-3) 0%,var(--ink-2) 45%,var(--ink) 100%);
  padding:1.8rem 1.9rem 1.9rem}

/* ==========================================================================
   5. VENDOR MARQUEE — bigger marks, more air, brighter at rest
   ========================================================================== */
.vend{padding-block:clamp(2.6rem,4.5vw,4rem)}
.v-item{margin-inline:clamp(4.4rem,8vw,7.4rem)}
.v-glyph{height:3.3rem}
.v-word{font-size:1.82rem}
.v-mark{opacity:.62;transition:opacity .28s,filter .28s,transform .28s}
.v-mark:hover,.v-mark:focus-visible{opacity:1;transform:translateY(-3px) scale(1.06);
  filter:drop-shadow(0 0 14px rgba(0,212,255,.55))}
.v-track{animation-duration:86s}

/* ==========================================================================
   6. THE NFTBAN DASHBOARD — the hero's proof, so it gets the room
   --------------------------------------------------------------------------
   It is the one place on the site that shows the product working. It gets a
   wider column, a lit ground behind it, and enough internal width that Greek
   words stop breaking mid-syllable.
   ========================================================================== */
.hero-grid{grid-template-columns:minmax(0,.92fr) minmax(0,1.28fr);
  gap:clamp(2.5rem,4.5vw,4.4rem)}
@media (max-width:74rem){.hero-grid{grid-template-columns:1fr}}

/* A cyan source sits behind the panel, not on it — the panel reads as lit
   rather than as outlined. */
.dash-wrap{position:relative}
.dash-wrap::before{content:"";position:absolute;inset:-14% -8% -18% -8%;pointer-events:none;
  background:radial-gradient(60% 55% at 60% 40%,rgba(0,212,255,.20),transparent 70%);
  filter:blur(18px);z-index:0}
.dash{position:relative;z-index:1}
.dash-top{padding-block:1.05rem}
.dash-top h2{font-size:1.08rem}
.pane{padding:1.15rem 1.2rem}
.pane h3{font-size:.66rem;letter-spacing:.16em}

/* The status block: a flex child cannot wrap until it may shrink, and
   break-word then split "Προστατευμένο" mid-syllable. Allow the shrink, forbid
   the break, and give the label a size that fits the column. */
.status{padding:.85rem .95rem;gap:.75rem}
.status>span{min-width:0}
.status b{font-size:.9rem;overflow-wrap:normal;word-break:normal;hyphens:none}
.status span span{font-size:.74rem}
.sets li{font-size:.78rem}
.sets .st{font-size:.66rem}
.feed li{padding-block:.6rem}
.feed .ev b{font-size:.9rem}

/* ==========================================================================
   7. MARQUEE SPACING — bigger marks need proportionally less gap, not more
   ========================================================================== */
.v-item{margin-inline:clamp(3.2rem,5.4vw,5rem)}

/* Measured: at 1920 the headline was breaking into six lines because the copy
   column was too narrow for 80px type. Widen the column and cap the top end —
   the headline stays the largest type on the site, but it reads as a headline
   rather than as a stack of syllables. Reserving four lines keeps the CTA row
   from jumping as the three statements rotate. */
.hero-grid{grid-template-columns:minmax(0,1.02fr) minmax(0,1.18fr)}
h1{font-size:clamp(2.5rem,4.5vw,4.4rem)}
.hero h1{min-height:calc(4 * 1.02em);margin:1.5rem 0 1.9rem}
@media (max-width:74rem){.hero h1{min-height:0}}

/* ==========================================================================
   8. FRAMEWORKS — four regulations, four identities
   --------------------------------------------------------------------------
   V8 gave the four frameworks a thin coloured top border and otherwise
   identical cards, so the page read as a regulatory handout: everything the
   same size, nothing leading. Each framework now owns a colour it keeps
   everywhere on the site, and the content inside is ranked — Αφορά / Τι
   απαιτεί / Τι αναλαμβάνουμε on the surface, the clause-level detail folded
   into a <details> so the card can be scanned in five seconds.

   The colours are measured, not picked: on --ink they run 10.40 / 8.05 / 9.61 /
   9.17 : 1, and their deep variants on white run 6.42 / 7.37 / 5.83 / 5.91 : 1.
   Amber is normally reserved for caution on this site; here it is GDPR's
   identity by the owner's instruction, and it appears on paper only.
   ========================================================================== */
.c-nis2{--fw:var(--fw-nis2);--fw-deep:var(--fw-nis2-deep);--fw-tint:#D6F8FF;--fw-edge:#94EDFF;--fw-wash:rgba(0,212,255,.11)}
.c-dora{--fw:var(--fw-dora);--fw-deep:var(--fw-dora-deep);--fw-tint:#F3EFFF;--fw-edge:#DFD6FF;--fw-wash:rgba(179,157,255,.11)}
.c-iso {--fw:var(--fw-iso); --fw-deep:var(--fw-iso-deep);--fw-tint:#E3F8EF;--fw-edge:#B5ECD8;--fw-wash:rgba(79,209,161,.11)}
.c-gdpr{--fw:var(--fw-gdpr);--fw-deep:var(--fw-gdpr-deep);--fw-tint:#FDF1E5;--fw-edge:#F9DBBB;--fw-wash:rgba(240,168,92,.11)}
.c-bcm {--fw:var(--fw-bcm); --fw-deep:var(--fw-bcm-deep); --fw-tint:#EBF3FF;--fw-edge:#C9E0FF;--fw-wash:rgba(127,180,255,.11)}

/* ---- Navigator: the question that triggers each framework ---------------- */
.fw-nav{display:grid;grid-template-columns:repeat(auto-fit,minmax(13.5rem,1fr));gap:1rem;
  margin-bottom:clamp(2rem,4vw,3.2rem)}
.fw-chip{display:grid;gap:.7rem;align-content:space-between;text-decoration:none;
  padding:1.25rem 1.35rem 1.15rem;border-radius:var(--r);background:var(--card);
  border:1px solid var(--edge);border-top:3px solid var(--fw-deep);
  box-shadow:var(--lift-1);transition:transform .24s cubic-bezier(.2,.7,.3,1),box-shadow .24s}
.fw-chip:hover{transform:translateY(-3px);box-shadow:var(--lift-2)}
.fw-chip .q{font-size:.94rem;line-height:1.4;color:var(--on-paper-dim)}
.fw-chip .a{font-family:Commissioner,Inter,sans-serif;font-weight:800;letter-spacing:-.03em;
  font-size:1.5rem;color:var(--fw-deep)}

/* ---- The cards ----------------------------------------------------------- */
.fw-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(24rem,1fr));gap:1.5rem}
.fw2{position:relative;overflow:hidden;border-radius:var(--r-lg);
  background:linear-gradient(180deg,#FFFFFF 0%,#FBFDFE 100%);
  border:1px solid var(--edge);box-shadow:var(--lift-1);
  padding:1.9rem 1.9rem 1.7rem;display:flex;flex-direction:column;
  transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s,border-color .28s}
/* the identity bar, and a wash of the framework colour across the top third */
.fw2::before{content:"";position:absolute;left:0;right:0;top:0;height:4px;background:var(--fw-deep)}
.fw2::after{content:"";position:absolute;left:0;right:0;top:0;height:55%;pointer-events:none;
  background:linear-gradient(180deg,var(--fw-wash),transparent)}
.fw2>*{position:relative;z-index:1}
.fw2:hover{transform:translateY(-4px);box-shadow:var(--lift-2);border-color:var(--fw-deep)}

/* The oversized acronym: identity at a glance, and the thing that stops four
   cards from looking like one card repeated. Decorative, so hidden from AT. */
.fw-acr{position:absolute;right:-.4rem;bottom:-1.6rem;z-index:0;
  font-family:Commissioner,Inter,sans-serif;font-weight:800;font-size:7.5rem;letter-spacing:-.06em;
  line-height:1;color:var(--fw);opacity:.11;pointer-events:none;user-select:none;
  transition:opacity .3s,transform .3s}
.fw2:hover .fw-acr{opacity:.17;transform:translateY(-4px)}

.fw-head{display:grid;grid-template-columns:auto minmax(0,1fr);gap:1rem;align-items:center;
  margin-bottom:1.4rem}
.fw-ico{width:2.1rem;height:2.1rem;border-radius:8px;display:grid;place-items:center;flex:none;
  color:var(--fw-deep);background:var(--fw-tint);border:1px solid var(--fw-edge)}
.fw-ico svg{width:1.1rem;height:1.1rem;fill:none;stroke:currentColor}
.fw-head h3{font-size:1.5rem;font-weight:800;letter-spacing:-.028em;color:var(--on-paper)}
.fw-law{font-size:.76rem;color:var(--on-paper-dim);margin-top:.28rem;line-height:1.45}
.fw-law .mono{font-size:.74rem}

.fw-body{margin:0;display:grid;gap:1.05rem}
.fw-body>div{display:grid;gap:.3rem}
.fw-body dt{font-family:"JetBrains Mono",monospace;font-size:.68rem;letter-spacing:.17em;
  text-transform:uppercase;font-weight:600;color:var(--fw-deep)}
.fw-body dd{margin:0;font-size:1.02rem;line-height:1.55;color:var(--on-paper-dim)}

/* Progressive disclosure: the clause-level list is available, not in the way. */
.fw-more{margin-top:1.35rem;border-top:1px solid var(--edge);padding-top:.9rem}
.fw-more summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:.5rem;
  font-family:"JetBrains Mono",monospace;font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--fw-deep);font-weight:600}
.fw-more summary::-webkit-details-marker{display:none}
.fw-more summary::after{content:"";width:.5rem;height:.5rem;border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;transform:rotate(45deg) translateY(-2px);transition:transform .22s}
.fw-more[open] summary::after{transform:rotate(-135deg) translateY(-1px)}
.fw-more ul{list-style:none;margin:.9rem 0 0;padding:0;display:grid;gap:.45rem}
.fw-more li{position:relative;padding-left:1.1rem;font-size:.95rem;line-height:1.5;color:var(--on-paper-dim)}
.fw-more li::before{content:"";position:absolute;left:0;top:.62em;width:.42rem;height:1px;background:var(--fw-deep)}

.fw-cta{margin-top:auto;padding-top:1.5rem;display:inline-flex;align-items:center;gap:.5rem;
  font-size:.98rem;font-weight:600;letter-spacing:-.008em;text-decoration:none;color:var(--fw-deep)}
.fw-cta:hover{color:var(--on-paper)}

@media (max-width:34rem){
  .fw2{padding:1.5rem 1.35rem 1.4rem}
  .fw-acr{font-size:5.5rem}
  .fw-head h3{font-size:1.32rem}
}

/* auto-fit put three cards on the first row and orphaned DORA on the second.
   Four frameworks are a 2x2, and equal-height rows make them read as peers. */
/* Five cards in a two-track grid orphan one. DORA is the narrowest in scope
   (financial entities only) and carries the least content, so it takes the full
   width at the end and lays its three fields out side by side. */
@media (min-width:62rem){
  .fw-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fw-grid>.fw2:last-child{grid-column:1/-1}
  .fw-grid>.fw2:last-child .fw-body{grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem}
}

/* ==========================================================================
   9. NFTBAN ARCHITECTURE — the strongest section after the hero
   --------------------------------------------------------------------------
   V8 described the product as eight equal cards, which is the one shape that
   cannot express "the enforcement happens in the kernel and everything else
   only fills sets". This composition says it structurally: a packet path down
   the left with the kernel node as its centre of gravity, and the sources that
   populate the sets listed beside it, feeding in.

   Every node is a concept the repository implements. Nothing here is invented:
   no eBPF, no BGP, no control plane, no AI.
   ========================================================================== */
.arch{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(1.8rem,4vw,3.4rem);align-items:stretch}
@media (max-width:62rem){.arch{grid-template-columns:1fr}}

.arch-path{display:grid;grid-template-rows:auto 1fr auto 1fr auto;justify-items:stretch}
.arch-node{border-radius:var(--r);padding:1.15rem 1.3rem;
  background:linear-gradient(180deg,var(--ink-3),var(--ink-2));
  border:1px solid var(--rule);display:grid;gap:.3rem}
.arch-node .k{font-size:1.02rem;font-weight:650;color:var(--on-dark);letter-spacing:-.012em}
.arch-node .v{font-size:.88rem;color:var(--on-dark-dim);line-height:1.45}
.arch-node .v.mono{font-size:.8rem;letter-spacing:.04em;color:var(--on-dark-faint)}

/* The kernel is where the decision is made, so it is the only lit surface. */
.n-kernel{background:linear-gradient(165deg,#12354F,var(--ink-3) 55%,var(--ink-2));
  border-color:var(--rule-lit);padding:1.5rem 1.5rem 1.35rem;
  box-shadow:inset 0 0 0 1px var(--wire),0 24px 60px -30px rgba(0,212,255,.55)}
.n-kernel .k{font-size:1.15rem;font-weight:700}
.arch-verdict{list-style:none;display:flex;flex-wrap:wrap;gap:.5rem;margin:.9rem 0 0;padding:0}
.arch-verdict li{font-family:"JetBrains Mono",monospace;font-size:.72rem;letter-spacing:.06em;
  padding:.3rem .7rem;border-radius:99px;border:1px solid currentColor;background:rgba(0,0,0,.18)}
.arch-verdict .ok{color:var(--ok)}
.arch-verdict .drop{color:var(--block)}
.arch-verdict .by{color:var(--on-dark-faint)}

/* Connector with a travelling pulse: the one motion on this page, and it means
   traffic moving toward the chain. */
.arch-link{position:relative;min-height:3.2rem;display:grid;place-items:center}
.arch-link::before{content:"";position:absolute;top:0;bottom:0;width:1px;
  background:linear-gradient(180deg,transparent,var(--rule-lit) 20%,var(--rule-lit) 80%,transparent)}
.arch-link .pulse{position:absolute;width:5px;height:5px;border-radius:50%;background:var(--cy);
  box-shadow:0 0 10px 2px rgba(0,212,255,.75);animation:arch-fall 2.6s cubic-bezier(.5,0,.6,1) infinite}
.arch-link .pulse.d2{animation-delay:1.3s}
@keyframes arch-fall{0%{top:2%;opacity:0}12%{opacity:1}88%{opacity:1}100%{top:96%;opacity:0}}

.arch-feeds{border-radius:var(--r);padding:1.5rem 1.6rem 1.4rem;
  background:linear-gradient(180deg,rgba(11,30,49,.75),rgba(7,21,34,.55));
  border:1px solid var(--rule);border-left:2px solid var(--cy)}
.arch-h{font-family:"JetBrains Mono",monospace;font-size:.7rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--cy);margin-bottom:1.1rem}
.arch-feeds ul{list-style:none;margin:0;padding:0;display:grid}
.arch-feeds li{display:grid;gap:.15rem;padding:.72rem 0;border-top:1px solid var(--rule)}
.arch-feeds li:first-child{border-top:0;padding-top:0}
.arch-feeds .fn{font-size:.98rem;font-weight:600;color:var(--on-dark)}
.arch-feeds .fd{font-size:.88rem;line-height:1.45;color:var(--on-dark-dim)}

.arch-guards{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1rem;
  margin-top:clamp(1.6rem,3vw,2.4rem)}
.guard{padding:1.15rem 1.25rem;border-radius:var(--r);border:1px solid var(--rule);
  background:rgba(11,30,49,.6)}
.gk{font-family:"JetBrains Mono",monospace;font-size:.68rem;letter-spacing:.17em;
  text-transform:uppercase;color:var(--cy);margin-bottom:.5rem}
.gv{font-size:.94rem;line-height:1.5;color:var(--on-dark-dim)}

@media (prefers-reduced-motion:reduce){
  .arch-link .pulse{animation:none;top:46%}
}

/* ==========================================================================
   10. PAGE VISUAL SYSTEMS
   --------------------------------------------------------------------------
   Three primitives, themed per page through --fw, so no two inner pages
   compose alike while the site still reads as one system:

     .flow   a staged rail        NIS2 · GDPR · Backup
     .pdca   a four-phase cycle   ISO/IEC 27001
     .zones  segmented perimeter  Firewall & endpoint

   Each carries motion that means something — a pulse advancing along a rail is
   a case moving through stages; a rotating arc is a management system that
   never stops. Both stop under prefers-reduced-motion.
   ========================================================================== */

/* ---- .flow ---------------------------------------------------------------- */
.flow{display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));gap:0;
  counter-reset:fl;position:relative}
.flow-step{counter-increment:fl;position:relative;padding:2.6rem 1.4rem 1.5rem 0}
.flow-step::before{content:"";position:absolute;left:0;right:0;top:1.05rem;height:1px;
  background:var(--rule)}
.sec:not(.dark) .flow-step::before{background:var(--edge)}
.flow-step:last-child::before{right:1.4rem}
.flow-step::after{content:counter(fl,decimal-leading-zero);position:absolute;left:0;top:0;
  width:2.1rem;height:2.1rem;border-radius:50%;display:grid;place-items:center;
  font-family:"JetBrains Mono",monospace;font-size:.68rem;font-weight:600;
  color:var(--fw,var(--cy));border:1px solid currentColor;background:var(--ink)}
.sec:not(.dark) .flow-step::after{background:var(--card);color:var(--fw-deep,var(--cy-deep));
  border-color:currentColor}
.flow-step h3{font-size:1.16rem;margin-bottom:.45rem;letter-spacing:-.018em}
.flow-step p{font-size:1rem;line-height:1.5;color:var(--on-paper-dim)}
.dark .flow-step p{color:var(--on-dark-dim)}
.flow-step .out{display:block;margin-top:.7rem;font-family:"JetBrains Mono",monospace;
  font-size:.7rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--fw-deep,var(--cy-deep))}
.dark .flow-step .out{color:var(--fw,var(--cy))}
/* the pulse that runs the whole rail */
.flow::after{content:"";position:absolute;left:0;top:1.05rem;width:7px;height:7px;margin-top:-3px;
  border-radius:50%;background:var(--fw,var(--cy));box-shadow:0 0 12px 2px currentColor;
  animation:flow-run 7s cubic-bezier(.55,0,.5,1) infinite}
@keyframes flow-run{0%{left:0;opacity:0}6%{opacity:1}94%{opacity:1}100%{left:100%;opacity:0}}
@media (max-width:52rem){
  .flow{grid-template-columns:1fr}
  .flow-step{padding:.4rem 0 1.6rem 3.1rem}
  .flow-step::before{left:1.05rem;right:auto;top:0;bottom:0;width:1px;height:auto}
  .flow-step:last-child::before{bottom:auto;height:2.1rem}
  .flow::after{display:none}
}

/* ---- .pdca ---------------------------------------------------------------- */
.pdca{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center}
@media (max-width:62rem){.pdca{grid-template-columns:1fr}}
.pdca-fig{margin:0;max-width:26rem;justify-self:center;width:100%}
.pdca-fig svg{width:100%;height:auto;display:block;overflow:visible}
.pdca-arc{fill:none;stroke-width:11;stroke-linecap:round;opacity:.85}
.pdca-track{fill:none;stroke:var(--rule-lit);stroke-width:1.5;opacity:.6}
.pdca-run{fill:none;stroke:#fff;stroke-width:11;stroke-linecap:round;
  stroke-dasharray:24 629.5;filter:drop-shadow(0 0 7px rgba(255,255,255,.6));
  animation:pdca-spin 11s linear infinite}
@keyframes pdca-spin{to{stroke-dashoffset:-653.5}}
.pdca-lbl{font-family:"JetBrains Mono",monospace;font-size:9.5px;letter-spacing:.14em}
.pdca-core{font-family:Commissioner,Inter,sans-serif;font-weight:800;font-size:26px;fill:var(--on-dark)}
.pdca-core-s{font-family:"JetBrains Mono",monospace;font-size:8px;letter-spacing:.18em;fill:var(--on-dark-faint)}
.pdca-keys{list-style:none;margin:0;padding:0;display:grid;gap:1.1rem}
.pdca-keys li{display:grid;grid-template-columns:auto minmax(0,1fr);gap:1rem;align-items:start;
  padding-bottom:1.1rem;border-bottom:1px solid var(--rule)}
.pdca-keys li:last-child{border-bottom:0;padding-bottom:0}
.pdca-keys .dot{width:.7rem;height:.7rem;border-radius:50%;margin-top:.45rem}
.pdca-keys h3{font-size:1.14rem;margin-bottom:.3rem}
.pdca-keys h3 .en{font-family:"JetBrains Mono",monospace;font-size:.66rem;letter-spacing:.15em;
  text-transform:uppercase;color:var(--on-dark-faint);margin-left:.55rem;font-weight:500}
.pdca-keys p{font-size:1rem;color:var(--on-dark-dim)}

/* ---- .zones --------------------------------------------------------------- */
.zones{display:grid;gap:1rem}
.zone{position:relative;border-radius:var(--r);padding:1.3rem 1.4rem 1.25rem 1.7rem;
  background:linear-gradient(90deg,rgba(11,30,49,.9),rgba(7,21,34,.6));
  border:1px solid var(--rule);overflow:hidden}
.zone::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--zc,var(--cy))}
.zone::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,var(--zw,rgba(0,212,255,.09)),transparent 42%)}
.zone>*{position:relative;z-index:1}
.zone-h{display:flex;flex-wrap:wrap;align-items:baseline;gap:.7rem;margin-bottom:.45rem}
.zone-h h3{font-size:1.1rem}
.zone-h .tagx{font-family:"JetBrains Mono",monospace;font-size:.68rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--zc,var(--cy))}
.zone p{font-size:.98rem;line-height:1.5;color:var(--on-dark-dim)}
.zone-rules{list-style:none;display:flex;flex-wrap:wrap;gap:.4rem;margin:.8rem 0 0;padding:0}
.zone-rules li{font-family:"JetBrains Mono",monospace;font-size:.7rem;color:var(--on-dark-dim);
  border:1px solid var(--rule-lit);border-radius:99px;padding:.26rem .68rem}
.z-edge{--zc:var(--block);--zw:rgba(242,112,79,.09)}
.z-dmz{--zc:var(--warn);--zw:rgba(240,168,92,.09)}
.z-lan{--zc:var(--cy);--zw:rgba(0,212,255,.09)}
.z-core{--zc:var(--ok);--zw:rgba(79,209,161,.09)}

@media (prefers-reduced-motion:reduce){
  .flow::after{animation:none;left:50%}
  .pdca-run{animation:none;opacity:0}
}

/* ==========================================================================
   11. SERVICES — NFTBan leads the set
   --------------------------------------------------------------------------
   Six equal white cards said all six are the same kind of thing. One of them
   is a product this firm wrote; the other five are services it performs. The
   proprietary card is the only dark surface in the grid, spans two columns on
   a wide screen, and is the only one that glows on hover.
   ========================================================================== */
.cards{gap:1.5rem}
.svc-ico{width:2rem;height:2rem;border-radius:8px;display:grid;place-items:center;
  margin-bottom:1rem;background:linear-gradient(160deg,#E8F4FA,#F5FAFD);
  border:1px solid #CFE4F0;transition:background .26s,border-color .26s,transform .26s}
.svc-ico{color:var(--cy-deep)}
.svc-ico svg{width:1.05rem;height:1.05rem;fill:none;stroke:currentColor}
.cd:hover .svc-ico{transform:translateY(-2px) rotate(-2deg);border-color:var(--cy-deep)}

.cd-own{background:linear-gradient(160deg,var(--ink-3) 0%,var(--ink-2) 52%,var(--ink) 100%);
  border-color:var(--rule-lit);position:relative;overflow:hidden}
.cd-own::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(46% 70% at 88% 12%,rgba(0,212,255,.20),transparent 68%)}
.cd-own>*{position:relative;z-index:1}
.cd-own h3{color:#fff;font-size:1.6rem}
.cd-own p{color:var(--on-dark-dim);max-width:52ch}
.cd-own .go{color:var(--cy)}
.cd-own .go:hover{color:#fff}
.cd-own .svc-ico{background:linear-gradient(160deg,rgba(0,212,255,.22),rgba(0,212,255,.06));
  border-color:rgba(0,212,255,.42);width:2.3rem;height:2.3rem}
.cd-own .svc-ico{color:var(--cy)}
.cd-own .svc-ico svg{width:1.2rem;height:1.2rem}
.cd-own:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.09),0 34px 74px -34px rgba(0,212,255,.55)}
/* Two columns and two rows: with six services and a 3-track grid, spanning the
   lead card 2x2 is the only arrangement that leaves no orphan cells — and it
   gives the proprietary product the footprint the brief asks for. */
@media (min-width:64rem){.cd-own{grid-column:span 2;grid-row:span 2}}
.own-badge{display:inline-block;align-self:start;margin-bottom:1.1rem;
  font-family:"JetBrains Mono",monospace;font-size:.64rem;letter-spacing:.19em;text-transform:uppercase;
  color:var(--cy);border:1px solid rgba(0,212,255,.42);border-radius:99px;padding:.34rem .8rem;
  background:rgba(0,212,255,.08)}
.own-specs{list-style:none;display:flex;flex-wrap:wrap;gap:.45rem;margin:1.4rem 0 0;padding:0}
.own-specs li{font-family:"JetBrains Mono",monospace;font-size:.72rem;letter-spacing:.03em;
  color:var(--on-dark-dim);border:1px solid var(--rule-lit);border-radius:99px;padding:.32rem .75rem;
  background:rgba(0,0,0,.22)}
.own-specs .mono{font-size:.72rem;color:var(--cy)}

/* ==========================================================================
   12. PROOF — asymmetric, and every row is checkable
   ========================================================================== */
.proof-split{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:start}
@media (max-width:64rem){.proof-split{grid-template-columns:1fr}}
.proof-say h2{font-size:clamp(1.75rem,2.9vw,2.55rem);max-width:16ch}
.proof-list{list-style:none;margin:0;padding:0;display:grid}
.proof-list li{display:grid;grid-template-columns:minmax(8rem,11rem) minmax(0,1fr);
  gap:.35rem 1.5rem;padding:1.25rem 0;border-top:1px solid var(--rule);align-items:baseline}
.proof-list li:first-child{border-top:0;padding-top:0}
.proof-list .pk{grid-row:1;font-family:"JetBrains Mono",monospace;font-size:.68rem;
  letter-spacing:.17em;text-transform:uppercase;color:var(--on-dark-faint)}
.proof-list .pv{grid-row:1;font-size:1.16rem;font-weight:650;color:var(--cy);letter-spacing:-.01em}
.proof-list .pv.mono{font-size:1.02rem;letter-spacing:.02em}
.proof-list .pv a{color:var(--cy);text-decoration:none;border-bottom:1px solid rgba(0,212,255,.35)}
.proof-list .pv a:hover{color:#fff;border-bottom-color:#fff}
.proof-list .pd{grid-column:2;font-size:.98rem;line-height:1.5;color:var(--on-dark-dim)}
.proof-list .pd a{color:var(--on-dark);text-decoration:underline;text-underline-offset:2px}
@media (max-width:40rem){
  .proof-list li{grid-template-columns:1fr}
  .proof-list .pv,.proof-list .pd{grid-column:1}
  .proof-list .pv{grid-row:auto}
}

/* ==========================================================================
   13. MOBILE
   --------------------------------------------------------------------------
   This block is last on purpose. A later unconditional rule silently beat an
   earlier media query — .hero-grid was re-declared while tuning the 1920
   composition, which left the phone rendering the hero as two columns about
   150px wide each, with the headline clipped. Every layout that must collapse
   is re-asserted here, after everything else, so that cannot happen again.

   The goal is not a shorter page. It is that a phone still gets the technical
   surfaces — the dashboard scrolls as a strip instead of stacking into a
   column of fragments, and the diagrams keep their structure.
   ========================================================================== */
@media (max-width:74rem){
  .hero-grid{grid-template-columns:1fr!important}
}
@media (max-width:62rem){
  .arch{grid-template-columns:1fr!important}
  .pdca{grid-template-columns:1fr!important}
  .proof-split{grid-template-columns:1fr!important}
  .phero-grid{grid-template-columns:1fr!important}
  .loop{grid-template-columns:1fr!important}
}

@media (max-width:46rem){
  /* Nothing may push the page sideways. */
  h1,h2,h3,.lede,p,li,dd,dt{overflow-wrap:break-word}
  h1{hyphens:none}
  .wrap{padding-inline:1.15rem}

  /* Type: still authoritative, but sized for a 390px measure. */
  h1{font-size:clamp(2.05rem,8.6vw,2.7rem);line-height:1.06}
  .phero-grid h1,.h1-long{font-size:clamp(1.75rem,7.4vw,2.3rem);line-height:1.14}
  h2{font-size:clamp(1.6rem,6.4vw,2rem)}
  .lede,.phero .lede{font-size:1.06rem}
  body{font-size:1.05rem}
  .cd p,.fr>p,.fw-body dd{font-size:1.02rem}

  /* The dashboard stays a product interface: its three panes become a
     snap-scrolling strip rather than three stacked fragments. */
  /* base.css defines explicit tracks here; without clearing them the panes
     stay in those tracks and grid-auto-columns never applies — the first pane
     collapsed to a 20px column of vertical letters. */
  .dash-grid{display:grid;grid-template-columns:none!important;grid-template-rows:none!important;
    grid-auto-flow:column;grid-auto-columns:86%;
    overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;
    gap:0;-webkit-overflow-scrolling:touch}
  .dash-grid::-webkit-scrollbar{display:none}
  .dash-grid>.pane{scroll-snap-align:start;border-right:1px solid var(--rule)}
  .dash-wrap::after{content:"Σύρετε για τα υπόλοιπα πάνελ →";display:block;
    margin-top:.6rem;font-family:"JetBrains Mono",monospace;font-size:.64rem;
    letter-spacing:.13em;color:var(--on-dark-faint)}
  .status b{font-size:.95rem}

  /* Framework cards keep their identity; the watermark shrinks so it stays
     texture rather than becoming the loudest thing on a small screen. */
  .fw-acr{font-size:4.6rem;bottom:-1rem}
  .fw2{padding:1.45rem 1.3rem 1.35rem}
  .fw-head h3{font-size:1.28rem}
  .fw-ico{width:1.9rem;height:1.9rem}
  .fw-nav{gap:.7rem}
  .fw-chip{padding:1rem 1.1rem}
  .fw-chip .a{font-size:1.3rem}

  /* Architecture: the rail keeps its direction, the feeds stay legible. */
  .arch-link{min-height:2.4rem}
  .n-kernel{padding:1.25rem 1.2rem 1.15rem}
  .arch-feeds{padding:1.25rem 1.2rem}
  .arch-guards{gap:.7rem}

  .own-specs{gap:.35rem}
  .own-specs li{font-size:.68rem;padding:.28rem .6rem}
  .svc-ico{width:1.85rem;height:1.85rem;margin-bottom:.8rem}
  .cd,.fr,.cred-group{padding:1.35rem 1.3rem 1.4rem}
  .bar-in{min-height:4.4rem}
  .brand .logo-full,.brand .logo-mark{height:2.5rem}
  .proof-list li{padding:1rem 0}
  .proof-say h2{max-width:none}
}

/* The cycle figure needs room outside the ring for its four phase labels. */
.pdca-fig svg{padding:.4rem}
.pdca-lbl{font-weight:600}

/* ==========================================================================
   14. PRINT / PDF
   --------------------------------------------------------------------------
   Reported: saving the homepage as a PDF produced solid black squares,
   circles and triangles where the icons should be. That is what an inline
   <svg> looks like when the CSS carrying `fill:none` is not applied — the SVG
   default fill is black. The icons now carry fill="none" stroke="currentColor"
   as presentation attributes, which no stylesheet can take away, and this
   block makes the rest of the page print like a document instead of like a
   screenshot of a dark website.
   ========================================================================== */
@media print{
  /* Belt and braces: whatever else happens, an icon is an outline. */
  svg{fill:none!important;stroke:currentColor!important}
  .v-glyph svg,.brand svg{fill:currentColor!important;stroke:none!important}

  /* Ink. A navy page costs a cartridge and reads worse on paper. */
  html,body{background:#fff!important;color:#111!important}
  .dark,.phero,.band,.sec,.bar,.foot,.cd,.fr,.fw2,.facts,.panel,.dash,.arch-node,
  .arch-feeds,.guard,.zone,.cred-group,.fw-chip,.tab-list li,.own-specs li,.idx-col a{
    background:#fff!important;color:#111!important;box-shadow:none!important;
    text-shadow:none!important;backdrop-filter:none!important}
  .dark h1,.dark h2,.dark h3,.dark p,.dark li,.dark dd,.dark dt,.dark a,
  .phero h1,.phero p,.band h2,.band p,.foot *{color:#111!important}
  .dark::before,.dark::after,.phero::before,.phero::after,.sec::before,
  .hero::after,.dash-wrap::before,.fw2::after,.zone::after{display:none!important}

  /* Keep the identity colours — they carry meaning — but as ink, not light. */
  .tag,.facts-h,.arch-h,.gk,.fw-body dt,.fw-cta,.idx-col h3,.cred-group h3{
    color:#0B658F!important}
  .c-nis2 .fw-body dt,.c-nis2 .fw-cta,.c-nis2 .fw-head h3{color:#0B658F!important}
  .c-dora .fw-body dt,.c-dora .fw-cta{color:#5B3FB8!important}
  .c-iso  .fw-body dt,.c-iso  .fw-cta{color:#0F7355!important}
  .c-gdpr .fw-body dt,.c-gdpr .fw-cta{color:#8A5A12!important}
  .fw-acr{opacity:.08!important;color:#111!important}

  /* Nothing moves, nothing is hidden behind a scroll interaction. */
  *,*::before,*::after{animation:none!important;transition:none!important}
  .rise{opacity:1!important;transform:none!important}
  .hero-fx,.v-marquee,.arch-link .pulse,.flow::after,.pdca-run,
  .menu-btn,.btn-head,.skip{display:none!important}
  /* base.css keeps three explicit tracks here; without clearing them the
     panes stay side by side on paper instead of stacking. */
  .dash-grid{display:grid!important;grid-template-columns:1fr!important;
    grid-auto-flow:row!important;overflow:visible!important}

  /* Folded detail must not vanish from a printed copy. */
  details>*{display:block!important}
  .faq summary::after,.fw-more summary::after{display:none!important}

  /* Borders instead of surfaces, and blocks that do not split across pages. */
  .cd,.fr,.fw2,.cred-group,.zone,.arch-node,.guard,.facts{
    border:1px solid #C8D2DC!important;break-inside:avoid}
  .fw2::before{background:#111!important}
  section{break-inside:auto}
  h1,h2,h3{break-after:avoid}

  /* On paper a link is only useful if you can read where it goes. */
  main a[href^="http"]::after{content:" (" attr(href) ")";font-size:.78em;color:#456;
    word-break:break-all}

  @page{margin:14mm}
}

/* ==========================================================================
   15. CONTACT FORM
   ========================================================================== */
.fm{max-width:52rem}
.fm-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.15rem 1.4rem}
.fm-wide{grid-column:1/-1}
.fm-f{display:grid;gap:.45rem;margin:0;max-width:none}
.fm-f label{font-family:"JetBrains Mono",monospace;font-size:.7rem;letter-spacing:.15em;
  text-transform:uppercase;font-weight:600;color:var(--on-paper-dim)}
.fm-f .req{color:var(--block)}
.fm input,.fm select,.fm textarea{
  font:400 1.02rem/1.5 Inter,system-ui,sans-serif;color:var(--on-paper);
  background:var(--card);border:1px solid var(--edge-2);border-radius:var(--r-sm);
  padding:.85rem 1rem;width:100%;transition:border-color .18s,box-shadow .18s}
.fm textarea{resize:vertical;min-height:9rem}
.fm select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--cy-deep) 50%),
  linear-gradient(135deg,var(--cy-deep) 50%,transparent 50%);
  background-position:calc(100% - 1.25rem) 1.35rem,calc(100% - .95rem) 1.35rem;
  background-size:6px 6px,6px 6px;background-repeat:no-repeat;padding-right:2.6rem}
.fm input:focus,.fm select:focus,.fm textarea:focus{outline:none;border-color:var(--cy-deep);
  box-shadow:0 0 0 3px rgba(11,101,143,.16)}

/* The honeypot must be unreachable for people and invisible to assistive tech,
   without display:none — some bots skip fields that are display:none. */
.fm-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.fm-consent{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.8rem;align-items:start;
  margin:1.5rem 0 0;max-width:none}
.fm-consent input{width:1.15rem;height:1.15rem;margin-top:.2rem;accent-color:var(--cy-deep)}
.fm-consent label{font-size:.95rem;line-height:1.5;color:var(--on-paper-dim)}
.fm-actions{display:flex;flex-wrap:wrap;align-items:center;gap:1.1rem;margin-top:1.6rem}
.fm-note{font-size:.9rem;color:var(--on-paper-dim)}

.fm-state{border-radius:var(--r);padding:1.1rem 1.3rem;margin-bottom:1.8rem;max-width:52rem;
  font-size:1.02rem;line-height:1.5;border-left:3px solid var(--ok);background:#EAF7F1;color:#14503B}
.fm-state[data-kind="bad"]{border-left-color:var(--block);background:#FDEDE8;color:#7A2E17}
@media (max-width:44rem){.fm-grid{grid-template-columns:1fr}}

/* ==========================================================================
   16. NFTBan mark, and the services index as editorial rows
   ========================================================================== */
.nft-split{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,.65fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center}
@media (max-width:64rem){.nft-split{grid-template-columns:1fr;gap:2.4rem}}
.nft-mark{margin:0;display:grid;justify-items:center;gap:1rem}
.nft-mark img{width:100%;max-width:19rem;height:auto;display:block;
  filter:drop-shadow(0 26px 46px rgba(0,0,0,.55)) drop-shadow(0 0 34px rgba(0,212,255,.22))}
.nft-mark figcaption{font-family:"JetBrains Mono",monospace;font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--on-dark-faint)}
.nft-mark .mono{color:var(--cy)}
@media (max-width:64rem){.nft-mark img{max-width:14rem}}

/* The catalogue was four bordered lists — a sitemap, and it read like one.
   One row per group: the group in the mono voice on the left, its services as
   flowing links on the right. Denser, scannable, and it stops competing with
   the composed sections underneath. */
.idx{display:grid;grid-template-columns:1fr;margin:0;gap:0}
.idx-row{display:grid;grid-template-columns:minmax(9rem,13rem) minmax(0,1fr);
  gap:.6rem 2rem;padding:1.35rem 0;border-top:1px solid var(--edge);align-items:baseline}
.idx-row:last-child{border-bottom:1px solid var(--edge)}
.idx dt{font-family:"JetBrains Mono",monospace;font-size:.72rem;letter-spacing:.19em;
  text-transform:uppercase;font-weight:600;color:var(--cy-deep)}
.idx dd{margin:0;display:flex;flex-wrap:wrap;gap:.4rem .5rem}
.idx dd a{display:inline-block;text-decoration:none;font-size:.97rem;line-height:1.3;
  color:var(--on-paper);padding:.34rem .78rem;border-radius:99px;
  border:1px solid var(--edge);background:var(--card);
  transition:border-color .18s,color .18s,transform .18s}
.idx dd a:hover{border-color:var(--cy-deep);color:var(--cy-deep);transform:translateY(-1px)}
@media (max-width:44rem){
  .idx-row{grid-template-columns:1fr;gap:.7rem;padding:1.1rem 0}
  .idx dd a{font-size:.9rem;padding:.3rem .68rem}
}

/* The message field is where the actual request gets written — give it room. */
.fm{max-width:64rem}
.fm textarea{min-height:13rem}

/* ==========================================================================
   17. Responsibility split — what stays with you, what we carry
   --------------------------------------------------------------------------
   A vCISO engagement fails when the boundary is vague, so the boundary is the
   visual: two columns, the client's side first and drawn as the heavier
   surface, because the accountability genuinely stays there.
   ========================================================================== */
.split2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.4rem}
@media (max-width:52rem){.split2{grid-template-columns:1fr}}
.split-col{border-radius:var(--r);padding:1.6rem 1.7rem 1.5rem;border:1px solid var(--edge);
  background:linear-gradient(180deg,#FFFFFF,#FAFCFE);box-shadow:var(--lift-1)}
.split-you{border-top:4px solid var(--on-paper)}
.split-us{border-top:4px solid var(--cy-deep)}
.split-h{font-family:"JetBrains Mono",monospace;font-size:.72rem;letter-spacing:.19em;
  text-transform:uppercase;font-weight:600;margin-bottom:1.1rem}
.split-you .split-h{color:var(--on-paper)}
.split-us .split-h{color:var(--cy-deep)}
.split-col ul{list-style:none;margin:0;padding:0;display:grid;gap:.75rem}
.split-col li{position:relative;padding-left:1.35rem;font-size:1.02rem;line-height:1.5;
  color:var(--on-paper-dim)}
.split-col li::before{content:"";position:absolute;left:0;top:.68em;width:.55rem;height:1px;
  background:currentColor;opacity:.6}
.dark .split-col{background:linear-gradient(180deg,var(--ink-3),var(--ink-2));border-color:var(--rule)}
.dark .split-col li{color:var(--on-dark-dim)}
.dark .split-you .split-h{color:var(--on-dark)}

/* --------------------------------------------------------------------------
   Map link. A link, never an embed: a Google Maps iframe loads third-party
   script and hands the visitor's IP to Google before any consent is given,
   which is the one thing a site selling GDPR compliance must not do. Clicking
   is a choice; loading is not.
   -------------------------------------------------------------------------- */
.map-link{display:inline-flex;align-items:baseline;gap:.35rem;text-decoration:none;
  border-bottom:1px solid transparent;transition:color .18s,border-color .18s}
.map-link:hover{border-bottom-color:currentColor}
.map-ico{font-size:.8em;opacity:.7}
.foot-col .map-link{color:var(--on-dark-dim)}
.foot-col .map-link:hover{color:var(--cy)}
.facts .map-link{color:var(--cy);font-size:.95rem;margin-top:.3rem}

/* ── Legal prose ──────────────────────────────────────────────────────────
   Terms and policy text is long, dense and read linearly rather than
   scanned, so it gets a narrower measure than the marketing sections and a
   looser leading. Numbered headings give a reader a way to cite a clause. */
.terms-body{max-width:38rem;counter-increment:clause}
.terms-body h2{font-size:clamp(1.2rem,1.7vw,1.45rem);line-height:1.3;margin:0 0 1.1rem}
.terms-body h2::before{content:counter(clause) ". ";opacity:.45;font-variant-numeric:tabular-nums}
.terms-body p{margin:0 0 1.05rem;line-height:1.75;font-size:1rem;color:var(--body)}
.terms-body p:last-child{margin-bottom:0}
.terms-list{margin:0 0 1.05rem;padding-left:1.15rem;line-height:1.7}
.terms-list li{margin:0 0 .4rem}
.terms-list li::marker{color:var(--fw-nis2);font-size:.85em}
body{counter-reset:clause}
.sec:has(.terms-body){padding-block:0}
.sec:has(.terms-body):first-of-type{padding-top:var(--gap)}
.sec:has(.terms-body) .terms-body{padding-block:1.6rem}
.sec:has(.terms-body)+.sec:has(.terms-body) .terms-body{border-top:1px solid var(--edge)}

/* The flagship card spans 2x2, so a three-line paragraph left two thirds of it
   empty and the box read as a missing image. Concrete capabilities fill it and
   do more work than decoration would. */
.cd-points{list-style:none;margin:1.5rem 0 0;padding:0;display:grid;gap:.72rem}
.cd-points li{position:relative;padding-left:1.15rem;line-height:1.6;
  font-size:.95rem;color:var(--on-dark-dim)}
.cd-points li::before{content:"";position:absolute;left:0;top:.62em;
  width:5px;height:5px;border-radius:50%;background:var(--cy);opacity:.85}
.cd-points b{color:#fff;font-weight:600}
