/* ============================================================
   ByteSynthify — shared stylesheet
   Enterprise theme · red #D71920 / #E1261C + white · deep black #080808
   Alternating sections: white content · deep charcoal · red-black gradient
   Type: Inter (UI) + JetBrains Mono (labels / technical accents)
   ============================================================ */

/* ============================================================
   DESIGN TOKENS — the single source of colour truth.
   Every colour used anywhere on the site resolves from here.
   Section themes (below) only re-point these tokens; they never
   introduce a new value. That is what keeps desktop / tablet /
   mobile identical: there is no per-breakpoint colour to drift.
   ============================================================ */
:root{
  /* ---- HEADER HEIGHT ----
     One number, because the fixed header is referenced as an offset in several
     places that must all agree: the sticky services tab bar, the two
     scroll-margin-top rules that let deep links clear it, and scroll-padding.
     Those all used to hard-code 64px.

     82px was set by the logo as originally supplied: assets/brand/logo.png
     arrived as a 2170x725 canvas, so at the header's 200px width it was 66.8px
     tall and would not fit the old 64px bar. That canvas has since been
     trimmed to 2034x464, which brings the same 200px logo down to 45.6px, so
     82px now leaves 18.2px above and below rather than the 7.6px it was
     tuned for. It is harmless - the tallest thing in the bar is now
     digital-marketing.html's own 200x50 mark - but the header is airier than
     it needs to be. About 68px would restore the original density if that is
     wanted; the number is one edit here and nothing else. */
  --hdr-h:82px;

  /* ---- RED SCALE ----
     Contrast measured against the light surfaces actually in use
     (#FFFFFF, #FAFAFA, #F7F7F7) and the dark ones:
       --red-600 #C4121A  5.6-6.0:1 on light  -> small red TEXT
       --red-500 #D71920  4.8:1 on #F7F7F7    -> fills, and small
                                                  text on the alt band
       --red-400 #E1261C  4.7:1 on #FFFFFF    -> large headings, hovers
       --red-300 #FF4B44  6.4:1 on #0D0D0D    -> red text on dark
       --red-200 #FF6A5E  7.2:1 on #0D0D0D    -> red on near-black art
     The old site used six unrelated reds for one job; these are the
     measured replacements. */
  --red-700:#A50F16;
  --red-600:#C4121A;         /* small text on light surfaces */
  --red-500:#D71920;         /* primary fill / brand */
  --red-400:#E1261C;         /* large text on light, hover states */
  --red-300:#FF4B44;         /* text on dark charcoal */
  --red-200:#FF6A5E;         /* text on the near-black artwork bands */

  /* ---- NEUTRAL SCALE ----
     Replaces ten ad-hoc near-blacks and greys that had drifted apart. */
  --n-0:#FFFFFF;
  --n-25:#FAFAFA;
  --n-50:#F7F7F7;
  --n-100:#EFEFEF;
  --n-200:#E5E5E5;
  --n-300:#D6D6D6;
  --n-400:#C8C8C8;
  --n-500:#8F8F8F;
  --n-600:#767676;
  --n-700:#4A4A4A;
  --n-800:#2E2E2E;
  --n-900:#141414;
  --n-950:#0D0D0D;
  --n-1000:#080808;

  /* ---- LEGACY ALIASES ----
     Unchanged names, now pointing at the scale above. Kept so the other
     five pages and every existing rule keep working untouched. */
  --bg:var(--n-0);
  --bg2:var(--n-950);
  --bg3:var(--n-900);
  --card:rgba(255,255,255,0.04);
  --card-hover:rgba(255,255,255,0.07);

  --brand:var(--red-500);
  --ink:var(--n-0);
  --dim:var(--n-400);
  --faint:var(--n-500);

  --accent:var(--red-500);
  --accent-2:var(--red-400);
  --accent2:var(--red-400);
  --accent-ink:var(--red-400);
  --accent-soft:rgba(215,25,32,0.14);
  --grad:linear-gradient(135deg,var(--red-500) 0%,var(--red-400) 100%);
  --grad-text:linear-gradient(135deg,var(--red-400) 0%,var(--red-500) 100%);
  --danger:var(--red-500);

  --line:rgba(255,255,255,0.15);

  /* ---- SHADOW / DEPTH ----
     Shadows carry a faint red ambient so dark surfaces read warm rather
     than muddy grey. This is the "premium" lever: depth without
     adding more colour to the page. */
  --shadow-sm:0 1px 2px rgba(20,4,4,0.10);
  --shadow:0 18px 40px -18px rgba(24,6,6,0.28);
  --shadow-lg:0 32px 72px -30px rgba(20,4,4,0.38);
  --shadow-red:0 16px 34px -14px rgba(215,25,32,0.30);

  --dark:var(--n-1000);
  --dark-2:var(--n-950);
  --on-dark:var(--n-0);
  --on-dim:var(--n-400);
  --on-faint:var(--n-500);
  --on-line:rgba(255,255,255,0.16);

  /* geometry */
  --r:12px;
  --r-lg:14px;
  --max:1160px;

  /* type */
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
}

/* ---- Section themes ----
   These blocks RE-POINT the root tokens for a surface type. They never
   introduce a value of their own, so every breakpoint inherits the same
   palette and there is nothing for a media query to override. */
/* Type A — white content sections (dark text, red accents) */
.section,.svc-panel,.svc-tabs-wrap,.svc-panels{
  position:relative;isolation:isolate;
  background:var(--n-0);
  --bg:var(--n-0); --bg2:var(--n-50); --bg3:var(--n-50);
  --card:var(--n-0); --card-hover:var(--n-25);
  --ink:var(--n-950); --dim:var(--n-700); --faint:var(--n-600);
  --accent-ink:var(--red-600);   /* 5.6-6.0:1 on white — safe for 11px labels */
  --line:var(--n-200);
  --shadow-sm:0 1px 2px rgba(20,4,4,0.10);
  --shadow:0 18px 40px -18px rgba(24,6,6,0.28);
  --shadow-lg:0 32px 72px -30px rgba(20,4,4,0.38);
}
/* Type B — deep charcoal sections (inline var(--bg2) bands) + subtle tech grid */
.section[style*="bg2"],.section.u-bg-alt{
  --bg:var(--n-950); --bg2:var(--n-950); --bg3:var(--n-900);
  --card:rgba(255,255,255,0.04); --card-hover:rgba(255,255,255,0.07);
  --ink:var(--n-0); --dim:var(--n-400); --faint:var(--n-500);
  --accent-ink:var(--red-300);   /* 6.4:1 on charcoal */
  --line:rgba(255,255,255,0.16);
  --shadow-sm:0 1px 2px rgba(0,0,0,0.45);
  --shadow:0 18px 40px -18px rgba(0,0,0,0.65);
  --shadow-lg:0 32px 72px -30px rgba(0,0,0,0.8);
}
.section[style*="bg2"]::after,.section.u-bg-alt::after{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(rgba(255,255,255,0.03) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,0.03) 1px,transparent 1px);
  background-size:64px 64px;
}

/* ---- Reset / base ---- */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--hdr-h) + 14px)}
body{
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  background:var(--bg);
  color:var(--dim);
  font-size:1rem;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:clip; /* clip, not hidden — hidden would make body a scroll container and break position:sticky */
}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
/* Imagery is decorative — clicks, drags, and selection do nothing. */
img{pointer-events:none;user-select:none;-webkit-user-select:none}
.bento-card.bento-dm,.bento-card.bento-support,
.bento-card.bento-svc-img1,.bento-card.bento-svc-img2,.bento-card.bento-wd-img,
.svc-shot,.story-img,.operation-media{cursor:default}
button{font-family:inherit}
::selection{background:var(--red-500);color:#fff}
:focus-visible{outline:2px solid var(--red-400);outline-offset:3px;border-radius:6px}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

.skip-link{position:absolute;left:-999px;top:0;background:var(--brand);color:var(--on-dark);padding:12px 20px;font-weight:600;z-index:10000}
.skip-link:focus{left:0}

.container{max-width:var(--max);margin:0 auto;padding:0 32px}

h1,h2,h3{font-family:'Inter',sans-serif;font-weight:700;line-height:1.08;letter-spacing:-0.03em;color:var(--ink)}
h1{font-size:clamp(2.6rem,5.6vw,4.4rem);line-height:1.06;letter-spacing:-0.03em}
h2{font-size:clamp(1.75rem,3.2vw,2.5rem);line-height:1.12;letter-spacing:-0.028em}
h3{font-size:clamp(1.05rem,1.4vw,1.2rem);font-weight:600;letter-spacing:-0.015em;line-height:1.3}
p{max-width:62ch;color:var(--dim);line-height:1.72}
.dim{color:var(--dim)}

.label{
  font-family:var(--mono);
  font-size:0.7rem;
  font-weight:600;
  letter-spacing:0.16em;
  text-transform:uppercase;
  color:var(--accent-ink);
}
.label::before{content:'';display:inline-block;width:18px;height:2px;background:var(--accent);margin-right:10px;vertical-align:middle;border-radius:2px}
/* On digital-marketing.html the section labels drop the mono face for the same
   font the display headings use - "Strategy first. / Creative second. / Data
   always." is Inter at weight 700.
   The stack is written out rather than inherited on purpose. h1,h2,h3 declare
   font-family:'Inter',sans-serif, which is NOT the body's longer
   'Inter',system-ui,-apple-system,'Segoe UI',sans-serif - so `inherit` here
   would land the label on the body stack. Both render in Inter, but the
   declarations would differ from the heading they are meant to match.
   letter-spacing drops 0.16em -> 0.08em: the old value is tuned for a mono
   face where every glyph is the same width, and 0.16em of tracking on 11.2px
   Inter opens the words into visible gaps.
   Scoped to .dm-band .label - exactly the six labels on this page. This is the
   only page in the site that uses .dm-band at all, so it cannot reach the
   labels on index / services / about / career / contact / 404. */
.dm-band .label{font-family:'Inter',sans-serif;letter-spacing:0.08em}
.hero .label,.cta .label{color:var(--red-300)} /* lifted red = AA on #080808..#52090C */

/* ---- Buttons ---- */
.btn{
  display:inline-flex;align-items:center;gap:9px;
  padding:14px 28px;
  border-radius:var(--r);
  font-size:0.9rem;font-weight:600;letter-spacing:-0.01em;
  font-family:'Inter',sans-serif;
  cursor:pointer;
  border:1px solid transparent;
  background:var(--brand);color:var(--on-dark);
  box-shadow:var(--shadow-sm);
  transition:all .25s ease;
}
.btn:hover{transform:translateY(-2px)}
.btn-primary{background:var(--brand);color:var(--on-dark)}
.btn-primary:hover{background:var(--red-400);color:#fff;box-shadow:0 14px 30px -12px rgba(215,25,32,0.55)}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line);box-shadow:none}
.btn-ghost:hover{background:var(--card-hover);border-color:var(--brand);color:var(--ink);box-shadow:var(--shadow-sm)}
.btn .arw{transition:transform .25s}
.btn:hover .arw{transform:translateX(3px)}

/* ---- Navigation: clean full-width bar ---- */
/* ============================================================
   HEADER / NAVIGATION — premium enterprise cybersecurity bar.

   CONTENT IS UNCHANGED. All five pages ship a byte-identical
   <nav id="navbar">: the same 5 labels (Home, Services, About,
   Careers, Contact), the same hrefs, the same inline SVG logo +
   "ByteSynthify" wordmark, the same #menuToggle hamburger, the
   same .nav-progress bar and the same #mobilePanel drawer. No
   label was renamed, added, removed or reordered, and there is
   no .nav-cta in the markup, so no CTA was invented here.

   Palette, per brand spec:
     --hdr-red       #D90000  fills, rules, dots, indicators
     --hdr-red-deep  #B80000  the one darker step (hover fills)
     --hdr-ink       #080808  bar base
     --hdr-deep      #111111  drawer base
     --hdr-paper     #FFFFFF  text
     --hdr-line      #E5E5E5  the light-mode hairline reference

   One deliberate deviation: --hdr-red-txt is a LIGHTER red than
   #D90000, used for link text on the near-black bar. #D90000 on
   #080808 measures 3.77:1, below the 4.5:1 that 11.8px uppercase
   text needs; #FF5147 measures 6.25:1 on the same background. The
   specified reds are still used verbatim wherever they are a fill
   or a rule rather than text.
   ============================================================ */
#navbar{
  --hdr-red:#D90000;
  --hdr-red-deep:#B80000;
  --hdr-red-txt:#FF5147;
  --hdr-ink:#080808;
  --hdr-deep:#111111;
  --hdr-paper:#FFFFFF;
  --hdr-line:#E5E5E5;

  position:fixed;
  top:0;
  left:0;right:0;
  z-index:1001;
  height:var(--hdr-h);          /* the logo sets this; see --hdr-h in :root */
  display:flex;align-items:center;justify-content:space-between;
  gap:18px;padding:0 28px;

  /* Translucent at rest so the hero reads straight through it; the
     faint 28px grid is the "very subtle grid texture" detail and is
     painted on the colour only, so it cross-fades with the state. */
  background-color:rgba(8,8,8,0.55);
  background-image:
    linear-gradient(rgba(255,255,255,0.016) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,0.016) 1px,transparent 1px);
  background-size:28px 28px,28px 28px;
  background-position:0 0,0 0;
  -webkit-backdrop-filter:blur(16px) saturate(140%);
  backdrop-filter:blur(16px) saturate(140%);
  border:0;
  border-radius:0;
  box-shadow:none;
  transition:background-color .32s ease,box-shadow .32s ease;
}
/* Top hairline with a single red segment at the left — the only
   always-on brand mark in the chrome. */
#navbar::before{
  content:'';position:absolute;left:0;right:0;top:0;height:1px;z-index:2;pointer-events:none;
  background:linear-gradient(90deg,var(--hdr-red) 0 76px,rgba(255,255,255,0.10) 76px 100%);
}
/* Bottom rule, separates the bar from the page without a heavy edge. */
#navbar::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:1px;z-index:1;pointer-events:none;
  background:rgba(255,255,255,0.07);
  transition:background-color .32s ease;
}
#navbar.scrolled{
  background-color:rgba(8,8,8,0.97);
  box-shadow:0 12px 32px -22px rgba(0,0,0,0.95);
}
#navbar.scrolled::after{background:rgba(255,255,255,0.13)}

.nav-progress{position:absolute;left:0;right:0;bottom:-1px;height:2px;background:transparent;overflow:hidden;pointer-events:none;z-index:2}
.nav-progress i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--hdr-red-deep),var(--hdr-red));transition:width .1s linear}
.brand{display:flex;align-items:center;gap:11px;font-size:1.1rem;font-weight:700;letter-spacing:-0.025em;color:var(--hdr-paper);flex:none;transition:opacity .22s ease}
.brand:hover{opacity:.86}
/* Brand logo file, used in the header and footer of index / services / about /
   career / contact. One file drives all ten placements (5 pages x 2), so
   swapping assets/brand/logo.png changes it everywhere; nothing else to edit.

   The asset is a 2034x464 horizontal lockup: a folded red mark, "ByteSynthify",
   and a two-line tagline. It is shown whole and uncropped in both the header
   and the footer, so each slot gets the mark, the name and the tagline, and
   nothing on the page has to state the name twice. That also makes the image
   the brand at both spots, so it carries alt="ByteSynthify" in the markup -
   there is no adjacent text left naming either link.

   Sizing mirrors .brand-mark on digital-marketing.html: a definite width, and
   the height follows from aspect-ratio. That is deliberate. The earlier version
   led with height and width:auto, which as a flex item collapses width onto
   the height, and it also made the visible result depend on the image's own
   intrinsic ratio - so a stale cached copy with the wrong ratio silently
   rendered as a small centred mark with no wordmark at all. Leading with width
   cannot fail that way: the box is always exactly as wide as declared, and
   contain keeps a mis-ratio source letterboxed instead of distorting it.

   aspect-ratio must be explicit. The img's width/height attributes do yield a
   computed "aspect-ratio: auto ...", but the auto form is ignored when height
   is auto, so without this the box falls back to the attributes' own 200/67 and
   drifts as the file changes.

   The file is assets/brand/logo.png, currently 2060x495 (aspect 4.16),
   trimmed to the artwork. Black background keyed out to RGBA with
   de-premultiplied edges. Note the wordmark is partly WHITE, so it is
   still only legible on this site's dark surfaces.

   Widths match digital-marketing.html exactly - 200px in the header, 240px in
   the footer. At those widths the artwork is ~48px and ~58px tall.
   There is deliberately no small-screen override, because .brand-mark has none
   either; 200px still leaves ~65px of clearance to the drawer toggle at a
   345px viewport. */
.brand-logo{
  width:200px;height:auto;
  aspect-ratio:2060/495;
  object-fit:contain;
  flex:none;display:block;
}
.footer-top .brand-logo{width:240px}
/* link group — right aligned */
.navlinks{display:none;align-items:center;gap:4px}
.navlinks a{
  position:relative;
  font-size:0.735rem;font-weight:600;
  letter-spacing:0.12em;text-transform:uppercase;
  color:rgba(255,255,255,0.76);
  padding:10px 14px;border-radius:8px;
  white-space:nowrap;
  transition:color .22s ease,background-color .22s ease;
}
/* tiny red indicator point, centred above the label */
.navlinks a::before{
  content:'';position:absolute;left:50%;top:3px;
  width:4px;height:4px;margin-left:-2px;border-radius:1px;
  background:var(--hdr-red);
  opacity:0;transform:translateY(-3px);
  transition:opacity .22s ease,transform .22s ease;
}
.navlinks a:hover{color:var(--hdr-red-txt);background:rgba(255,255,255,0.06)}
.navlinks a:hover::before{opacity:.6;transform:none}
/* keyboard focus */
.navlinks a:focus-visible,.brand:focus-visible,.menu-btn:focus-visible{
  outline:2px solid var(--hdr-red-txt);outline-offset:2px;color:var(--hdr-paper);
}
.navlinks a.current{color:var(--hdr-red-txt)}
.navlinks a.current::before{opacity:1;transform:none}
/* thin red underline under the active page, ends clipped to an angle */
.navlinks a.current::after{
  content:'';position:absolute;left:14px;right:14px;bottom:4px;height:2px;
  background:var(--hdr-red);
  clip-path:polygon(0 0,100% 0,calc(100% - 2px) 100%,2px 100%);
}
/* .nav-cta kept for parity with the shared stylesheet. No page currently
   renders one, so no CTA has been added to the header. */
.navlinks a.nav-cta{
  margin-left:10px;padding:10px 20px;border-radius:10px;
  background:var(--hdr-red);color:#fff;font-weight:600;
  transition:background-color .22s ease,box-shadow .22s ease;
}
.navlinks a.nav-cta:hover{background:var(--hdr-red-deep);color:#fff;box-shadow:0 10px 24px -12px rgba(217,0,0,0.7)}
.navlinks a.nav-cta.current{background:var(--hdr-red-deep)}
.navlinks a.nav-cta.current::after,.navlinks a.nav-cta::before{display:none}
.menu-btn{display:flex;flex-direction:column;gap:5px;cursor:pointer;padding:9px;z-index:1100;background:none;border:none;flex:none}
.menu-btn span{width:22px;height:2px;background:var(--hdr-paper);border-radius:2px;transition:all .3s}
.menu-btn:hover span{background:var(--hdr-red-txt)}
.menu-btn.active span{background:var(--hdr-red)}
.menu-btn.active span:nth-child(1){transform:rotate(45deg) translate(5px,5px)}
.menu-btn.active span:nth-child(2){opacity:0}
.menu-btn.active span:nth-child(3){transform:rotate(-45deg) translate(5px,-5px)}

.mobile{
  position:fixed;inset:0;
  /* Deep black per the brand spec, lifted slightly at the top-left with a
     red radial so the drawer carries the same cybersecurity accent as the
     bar. Faint 28px grid, matching #navbar. */
  background-color:rgba(17,17,17,0.985);
  background-image:
    radial-gradient(120% 80% at 6% 0%,rgba(217,0,0,0.16),rgba(17,17,17,0) 58%),
    linear-gradient(rgba(255,255,255,0.016) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,0.016) 1px,transparent 1px);
  background-size:auto,28px 28px,28px 28px;
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  z-index:999; /* sits under nav (1001) so the toggle stays visible as the close button */
  display:flex;flex-direction:column;align-items:flex-start;
  justify-content:center;gap:6px;padding:100px 40px 40px;
  transform:translateY(-12px);opacity:0;pointer-events:none;
  /* visibility (not only opacity/pointer-events) so the closed panel's links
     leave the tab order and the accessibility tree - WCAG 2.4.3 / 4.1.2 */
  visibility:hidden;
  transition:all .3s ease;
}
.mobile.active{opacity:1;transform:translateY(0);pointer-events:auto;visibility:visible}
.mobile a{
  position:relative;
  font-weight:700;font-size:clamp(1.7rem,7vw,2.1rem);letter-spacing:-0.03em;color:var(--hdr-paper,#fff);
  padding:8px 0;display:flex;align-items:baseline;gap:14px;
  opacity:0;transform:translateY(14px);transition:opacity .4s ease,transform .4s ease,color .2s;
}
.mobile.active a{opacity:1;transform:none}
/* thin red indicator point, aligned to the existing mono number */
.mobile a i{font-family:var(--mono);font-style:normal;font-size:0.68rem;font-weight:600;letter-spacing:0.1em;color:var(--hdr-red-txt,#FF5147);width:26px;flex:none;transition:color .2s}
.mobile a.current{color:var(--hdr-red-txt,#FF5147)}
.mobile a.current i{color:var(--hdr-red,#D90000)}
/* The drawer mirrors the .navlinks active state, but main.js only sets
   aria-current on the desktop rail (it queries '.navlinks > a'), so without
   this the current page is announced but not indicated here. */
.mobile a[aria-current="page"]{color:var(--hdr-red-txt,#FF5147)}
.mobile a[aria-current="page"] i{color:var(--hdr-red,#D90000)}
.mobile a[aria-current="page"]::after{height:72%}
/* angular accent that grows in from the left on hover/active */
.mobile a::after{
  content:'';position:absolute;left:-14px;top:50%;height:0;width:3px;
  background:var(--hdr-red,#D90000);
  transform:translateY(-50%);
  transition:height .24s ease;
}
.mobile a:hover{color:var(--hdr-red-txt,#FF5147)}
.mobile a:hover::after{height:56%}
.mobile a.current::after{height:72%}
.mobile .m-meta{
  margin-top:26px;padding-top:22px;border-top:1px solid rgba(255,255,255,0.12);
  width:100%;font-size:0.85rem;color:rgba(255,255,255,0.56);
  opacity:0;transition:opacity .4s ease .28s;
}
.mobile.active .m-meta{opacity:1}
@media(min-width:920px){.navlinks{display:flex}.menu-btn{display:none}}
/* Tablet: tighten the rail so all five labels stay on one line down to the
   920px switch-over. Labels, order and hrefs are untouched - only the
   horizontal rhythm changes. */
@media(min-width:921px) and (max-width:1180px){
  #navbar{padding:0 22px}
  .navlinks{gap:2px}
  .navlinks a{padding:10px 10px;font-size:0.7rem;letter-spacing:0.1em}
  .navlinks a::before{top:2px}
  .navlinks a.current::after{left:10px;right:10px}
}

/* ---- Breadcrumbs ---- */
.crumb{
  display:flex;align-items:center;gap:8px;
  font-family:var(--mono);
  font-size:0.7rem;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;
  color:var(--on-faint);margin-bottom:22px;
}
.crumb a{color:var(--on-dim)}
.crumb a:hover{color:var(--red-300)}
.crumb .sep{opacity:.45}

/* ---- Hero (cinematic deep black / dark red) ---- */
.hero{
  position:relative;isolation:isolate;
  display:flex;align-items:center;
  min-height:56vh;
  padding:112px 0 76px;
  overflow:hidden;
  background:var(--n-1000);
}
.hero::before{
  content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    url('hero-lines.webp') center/cover no-repeat,
    radial-gradient(58% 70% at 78% 26%,rgba(82,9,12,0.55),transparent 62%),
    radial-gradient(48% 62% at 10% 90%,rgba(48,5,7,0.6),transparent 70%),
    radial-gradient(30% 42% at 62% 62%,rgba(215,25,32,0.10),transparent 72%),
    linear-gradient(rgba(255,255,255,0.035) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,0.035) 1px,transparent 1px);
  background-size:cover,auto,auto,auto,64px 64px,64px 64px;
  animation:heroGlow 16s ease-in-out infinite alternate;
}
@keyframes heroGlow{from{opacity:.85}to{opacity:1}}
.hero .container{width:100%} /* flex item would otherwise shrink-to-fit and drift off the grid */
.hero-bg{position:absolute;inset:0;z-index:0}
.hero-bg img{width:100%;height:100%;object-fit:cover;opacity:0.55;filter:grayscale(0.3) contrast(1.08);pointer-events:none}
.hero-bg video{width:100%;height:100%;object-fit:cover;opacity:0.7;filter:grayscale(0.3) contrast(1.04) brightness(1.85);pointer-events:none} /* dark footage still reads under the hero overlay */
.hero-bg::after{
  content:'';position:absolute;inset:0;z-index:1;
  background:
    linear-gradient(90deg,rgba(8,8,8,0.97) 0%,rgba(8,8,8,0.9) 40%,rgba(13,13,13,0.55) 70%,rgba(48,5,7,0.5) 100%),
    linear-gradient(180deg,rgba(8,8,8,0.92) 0%,rgba(48,5,7,0.4) 55%,rgba(8,8,8,0.88) 100%);
}
.hero-inner{position:relative;z-index:2;max-width:1040px}
.hero .label{margin-bottom:22px;display:block}
.hero h1{margin-bottom:24px;color:var(--n-0);font-weight:300;letter-spacing:-0.02em;line-height:1.14}
.hero h1 em{
  font-style:normal;display:block;font-weight:700;letter-spacing:-0.03em;
  background:linear-gradient(135deg,var(--red-400) 0%,var(--red-500) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* "Future." carries a solid red plate so the closing word reads as the payoff.
   It sits inside <em>, which paints its text through background-clip:text, so
   this has to undo two INHERITED properties before it can show a normal
   background of its own:
     color:transparent                  -> repaint the glyphs white
     -webkit-text-fill-color:transparent (inherited from the parent's clip)
     background-clip:text -> border-box, so the plate is a real box
   Deliberately NOT display:inline-block. A vertical padding on an inline-block
   expands the line box, which pushed the whole hero (and the document) 12px
   taller. On a plain inline element vertical padding paints but does not
   affect the line box, so the plate is purely visual and the page height is
   unchanged. Horizontal padding still reserves the side spacing, and em units
   keep the plate proportional at every font size.
   Kept as a class, not an inline style: the CSP sets style-src-attr 'none',
   so a style="" attribute here would be silently dropped.
   White on the lightest stop (#D71920) is 5.19:1, on the darkest 6.04:1. */
.hero h1 em .hero-hl{
  color:var(--n-0);
  -webkit-text-fill-color:var(--n-0);
  background:linear-gradient(180deg,var(--red-500) 0%,var(--red-600) 100%);
  -webkit-background-clip:border-box;
  background-clip:border-box;
  padding:.06em .13em .02em;
  margin:0 -.01em;
  border-radius:.1em;
  box-shadow:inset 0 -.04em 0 rgba(0,0,0,.22);
}
/* Breathing room between the two display lines of hero headlines.
   Headlines are set at line-height:1.14, which left the two lines' em-boxes
   OVERLAPPING by 4.8px at 1440 - the headline read as one dense block. 0.2em
   takes the baseline-to-baseline distance from 1.14x to 1.34x the font size,
   which is the usual display leading for a deliberate two-part lockup.

   In em, not px, so the gap stays proportional to the clamp()'d font size at
   every breakpoint: ~14px at 1440, ~8px at 768, ~8px at 390.

   Applies to every hero: all five pages now use the same two-part lockup. */
.hero h1 em{
  margin-top:.2em;
}
.hero .lede{font-size:1.08rem;line-height:1.76;max-width:56ch;color:var(--on-dim)}
.hero-actions{display:flex;flex-wrap:wrap;gap:14px;margin-bottom:44px}
.home-hero-actions{margin-top:28px}
.hero-actions:last-child{margin-bottom:0}
.hero .btn-primary{background:var(--accent);color:#fff;border-color:transparent}
.hero .btn-primary:hover{background:var(--red-400);color:#fff;box-shadow:0 16px 36px -14px rgba(215,25,32,0.7)}
.hero .btn-ghost{color:var(--on-dark);border-color:rgba(255,255,255,0.3)}
.hero .btn-ghost:hover{background:rgba(255,255,255,0.1);border-color:rgba(255,255,255,0.6);color:#fff;box-shadow:none}
.trust-row{
  position:relative;z-index:2;
  display:flex;flex-wrap:wrap;gap:10px 26px;align-items:center;
  margin-top:40px;padding-top:24px;border-top:1px solid rgba(255,255,255,0.15);
}
.trust-row span{
  font-family:var(--mono);font-size:0.68rem;font-weight:500;letter-spacing:0.13em;
  text-transform:uppercase;color:rgba(255,255,255,0.6);
  display:inline-flex;align-items:center;gap:8px;
}
.trust-row span::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--accent)}

/* ---- Sections ---- */
.section{padding:104px 0}
.section-header{margin-bottom:52px}
.section-header .label{display:block;margin-bottom:16px}
.section-header h2{margin-bottom:14px}
.section-header p{max-width:56ch}

.split{display:grid;grid-template-columns:1fr 1fr;gap:52px;align-items:stretch}
@media(max-width:860px){.split{grid-template-columns:1fr}}


/* ---- Homepage services bento preview (white page, black cards, home only) ---- */
.section.services-preview{
  /* Background artwork: gradient stays on top, image beneath, white as the
     final fallback layer. Source: assets/bento/background_1440x838.webp (28 KB).
     That artwork is authored 1440 x 838 but this section measures 1440 x 1026
     at a 1440px viewport, so `cover` upscales it ~1.22x and trims the sides.
     Fine for this soft abstract art; re-author at 1440 x 1026 if you want it
     pixel-exact here. */
  background:
    radial-gradient(55% 34% at 50% -6%,rgba(158,20,20,0.10),rgba(255,255,255,0) 70%),
    url('assets/bento/background_1440x838.webp') center center/cover no-repeat,
    var(--n-0);
  border-top:1px solid rgba(10,10,10,0.08);
  border-bottom:1px solid rgba(10,10,10,0.10);
  --ink:var(--n-950); --dim:var(--n-700); --faint:var(--n-600);
  --line:rgba(10,10,10,0.12);
  --card:var(--n-900); --card-hover:#1A1A1A;
  --accent:var(--red-500); --accent-2:var(--red-400); --accent-ink:var(--red-600);
  --accent-soft:rgba(225,38,28,0.16);
  --grad:linear-gradient(135deg,var(--red-400) 0%,#FF2B22 100%);
  --shadow:0 24px 60px -30px rgba(0,0,0,0.25);
  --shadow-lg:0 32px 80px -36px rgba(0,0,0,0.3);
}
.services-preview .section-header{text-align:center}
.services-preview .section-header .label{display:inline-flex;align-items:center}
.services-preview .section-header p{margin-left:auto;margin-right:auto;color:var(--dim)}

/* "Our services" compacted - 146px off the section at 1440 (1258 -> 1112).
   Same columns, same grid-template-areas, same colours, same type, same card
   styling. The changes are spacing, plus one row height:
     padding        64/104 -> 48/56   both sides; 64 came from .hero + .section
     header gap      52 -> 28
     label gap       16 -> 12
     h2 gap          14 -> 10
     grid gap        22 -> 12
     bottom row     210 -> 180

   The bottom row is the only row touched, and it is the only one with room:
   the gth card is full-width and its content needs 114px of the 210px, so it
   has ~96px spare. Rows 1 and 2 are deliberately left at 290px - the
   Consulting card in row 2 already has just 17px of bottom padding left at
   1024px (306px of content in a 288px box), and shortening those rows would
   clip it. That pre-existing squeeze is unchanged by this work.

   Row heights are set on the shared .bento-grid rather than scoped to
   #services-preview on purpose: an ID selector here would outrank the
   max-width:980px and max-width:640px media queries further down that reset
   grid-template-rows for tablet and mobile, and force three fixed rows onto
   the stacked layouts. Bare .bento-grid appears on index.html only - the two
   grids on digital-marketing.html carry --svc / --wd, which set their own rows
   at every breakpoint. */
#services-preview{padding:48px 0 56px}
#services-preview .section-header{margin-bottom:28px}
#services-preview .section-header .label{margin-bottom:12px}
#services-preview .section-header h2{margin-bottom:10px}
#services-preview .bento-grid{gap:12px}

/* "Why businesses trust us" compacted with the same values as the section
   above, so the two sit at the same rhythm rather than one being visibly
   tighter than its neighbour. Same reasoning: spacing only, no change to the
   cards, the type, or the colours. 146px comes off the section at 1440
   (838 -> 692), and it is all available without touching card padding.

   .trust-grid has no fixed row heights - it is align-items:stretch over
   two rows of three, so its height follows its content and the section was
   almost entirely padding. Nothing clips at any width before or after.

   The grid gap is set inside min-width:961px rather than as a plain
   `#why-trust-us .trust-grid` rule on purpose. An ID selector here would
   outrank the max-width:960px and max-width:620px media queries further down
   that widen the gap for the 2-up and 1-up layouts, collapsing a deliberate
   22 / 18 / 14 progression to a flat 12. Scoped to the range where the base
   .trust-grid{gap:22px} actually applies, those two breakpoints still win. */
#why-trust-us{padding:48px 0 56px}
#why-trust-us .section-header{margin-bottom:28px}
#why-trust-us .section-header .label{margin-bottom:12px}
#why-trust-us .section-header h2{margin-bottom:10px}
/* Asymmetric card heights, desktop only (3-up and wider).

   Multi-column layout rather than grid, because that is the only approach that
   gives genuinely different heights per card without hard-coding any of them.
   Grid with align-items:stretch pins every card in a row to the tallest, and
   grid-row:span N would have to hard-code a height that is correct at one
   width and clips the copy at another - the six cards measure anywhere from
   117px to 278px of natural height depending on the viewport, and .trust-card
   is overflow:hidden, so a wrong span silently cuts text.

   Columns also cannot clip: each card is its own content height, and
   break-inside:keep stops one being split across a column boundary.

   Measured natural heights at 1440 are 229 / 179 / 154 / 179 / 154 / 154, a
   75px spread, so the three columns finish at three different heights and the
   block reads as staggered rather than banded. Reading order runs down each
   column, which is the one trade-off of this technique.

   Scoped to min-width:961px so the 2-up and 1-up grid layouts below 960 keep
   working - including .trust-card.lead{grid-column:1/-1}, which is a grid
   property and would do nothing under columns. The gap becomes a column-gap,
   and margin-bottom on the card does the stacking that row-gap used to do. */
@media(min-width:961px){
  #why-trust-us .trust-grid{display:block;columns:3;column-gap:12px}
  #why-trust-us .trust-card{
    break-inside:avoid;-webkit-column-break-inside:avoid;
    margin-bottom:12px;
  }
}

/* "Enterprise-grade protection" - the first trust card - given the same
   brand-red fill as the two bento cards above. This card is a .trust-card.lead,
   which is #0B0B0C with a white h3 and #A0A0A5 body, so three things move with
   the fill, not one:
     background   #0B0B0C -> #D71920
     body p       #A0A0A5 on red is 1.96:1, well under the 4.5 that 14.72px
                  copy needs, so it goes white. #E8E8EA was tried and still
                  only reached 4.18:1 - white is the only clean option here.
     border       the markup carries u-border-red, and .u-border-red.u-border-red
                  is (0,2,0) against .trust-card.lead's (0,2,0) but sits later
                  in this file, so the border was resolving to #E3131E - which
                  is 1.07:1 on a red fill, i.e. invisible. Pinned to #0B0B0C,
                  matching the black hairlines used on the bento cards and the
                  service screenshots. Against the light band that is the
                  border's real job, #0B0B0C measures 19.67:1.
   The h3 needs nothing: .trust-card.lead h3 is already var(--n-0), and white
   on red is 5.11:1. It is 18.4px bold, just under the 18.66px that WCAG counts
   as large text, so it is held to 4.5 - which it still clears.

   Scoped to the first card by position, not to .lead - there are three lead
   cards and only this one was asked for. The other two, "Proactive, not
   reactive" and "Transparent communication", stay #0B0B0C. */
#why-trust-us .trust-grid > .trust-card:first-child{background:linear-gradient(180deg,var(--red-500) 0%,var(--red-600) 100%);border-color:#0B0B0C}
#why-trust-us .trust-grid > .trust-card:first-child:hover{border-color:#0B0B0C}
#why-trust-us .trust-grid > .trust-card:first-child p{color:var(--n-0)}
#why-trust-us .trust-grid > .trust-card:first-child .trust-n{color:#fff}
#why-trust-us .trust-grid > .trust-card:first-child .trust-n::after{background:rgba(255,255,255,0.4)}
#why-trust-us .trust-grid > .trust-card:first-child::before{display:none}

/* "How we work" compacted, third section on the page, with the same values as
   the two above it so all three share one rhythm. 154px comes off at 1440.

   This is the one section on the page that had no id, so one was added. The
   alternatives were worse: u-bg-alt is shared with about / career / contact,
   and .process plus .step are shared with contact.html (process cols-3) and
   digital-marketing.html (process dm-flow) - six of its .step cards are the
   #process section there. Scoping by id is what keeps those three pages out of
   it, and it matches how #services-preview and #why-trust-us are already
   scoped. Every rule below is prefixed for that reason.

   The grid gap is inside min-width:861px for the same reason as the trust
   grid: max-width:860px and max-width:520px re-space .process for the 2-up
   and 1-up layouts, and an unscoped id rule would outrank both and flatten
   the 26 / 30 / 22 progression to a single value. */
#how-we-work{padding:48px 0 56px}
#how-we-work .section-header{margin-bottom:28px}
#how-we-work .section-header .label{margin-bottom:12px}
#how-we-work .section-header h2{margin-bottom:10px}
@media(min-width:861px){#how-we-work .process{gap:14px}}
#how-we-work .step{padding-top:24px}

/* Red-filled bento cards: "01 / Cybersecurity" (.bento-featured, top-left) and
   "04 / Digital Marketing & Web Design" (.bento-growth, full-width footer). Both
   are index.html only, and both get the identical treatment, so they share one
   set of rules rather than being written twice. Scoped on the page id rather
   than on the bare classes, so the red cannot follow the element onto another
   page if it is ever reused.

   The copy has to change with the fill. Measured against #D71920:
     .bento-tag  #FF2B22  1.37:1  - red on red, invisible
     body p      #B5B5B5  2.49:1  - fails the 4.5 that 14.88px copy needs
     h3          #FFFFFF 5.11:1  - already fine
     .bento-cta  #FFFFFF 5.11:1  - already fine
   So the tag and the paragraph go white as well. Hierarchy then rests on size
   and weight: the tag is 0.68rem mono uppercase, the h3 is bold.

   The hover border goes white because the shared .bento-card:hover tints it to
   rgba(225,38,28,.55) - red on a red fill, invisible. These selectors do beat
   that one: (1,2,1) against (0,2,0).

   The CTA pill also has to diverge on hover. .bento-cta is a bordered pill and
   the shared .bento-card:hover .bento-cta fills it with var(--red-500), which
   reads as an accent on a black card but would be a red pill on a red fill
   with its border gone - the affordance would disappear under the pointer. So
   both cards take a black pill on hover and a stronger resting border, and the
   label stays the white it already rests at. (1,3,0) against the shared
   (0,3,0), so the id decides it,
   not source order - the shared rule sits later in this file and would win on
   order alone. Only the colour is pinned; the .arw still slides 6px, a
   transform on a white arrow that stays legible.

   The shared ::before top bar and ::after radial wash are left alone. They are
   red-on-red once the fill is red, but they are hover-only (opacity 0 at rest)
   and the top bar's glow spreads outside the card onto the white band, where
   it still reads. Recolouring them would be invisible work. */
#services-preview .bento-featured,
#services-preview .bento-growth{background:var(--red-500);border-color:#0B0B0C}
#services-preview .bento-featured .bento-tag,
#services-preview .bento-growth .bento-tag{color:#0B0B0C}
#services-preview .bento-featured .bento-body p,
#services-preview .bento-growth .bento-body p{color:var(--n-0)}
/* Black hairline at rest AND on hover, replacing the white 0.72 the hover used
   to jump to. Same #0B0B0C the service screenshots on services.html now use.
   On a red fill a white hover border was the wrong signal - the card already
   announces itself - and it fought the black frame. The hover affordance is
   the 4px lift and the shadow, both of which are untouched, so nothing is lost
   by holding the border still. The two red cards are pinned together because
   they sit in the same grid and a black frame on one but not the other would
   read as a mistake.

   The border's contrast is measured against the light band the card sits on,
   not against its own fill: #0B0B0C on that is 19.67:1, well past the 3:1 WCAG
   asks of a visible boundary. */
#services-preview .bento-featured:hover,
#services-preview .bento-growth:hover{border-color:#0B0B0C}
#services-preview .bento-featured .bento-cta,
#services-preview .bento-growth .bento-cta{border-color:rgba(255,255,255,0.5)}
#services-preview .bento-featured:hover .bento-cta,
#services-preview .bento-growth:hover .bento-cta{background:#0B0B0C;border-color:transparent;color:var(--n-0)}

/* The two illustration cards - .bento-dm (assets/bento/01.svg) and
   .bento-support (02.svg) - lose the darkening that was baked over them.
   Two separate things were doing it, and both are removed:
     .bento-media::after  a vignette, radial 0 -> 45% black at the edges plus
                         a top/bottom linear wash of 12% and 28%
     .bento-media img     filter:saturate(.88) contrast(1.04) brightness(.94)
                         - that .94 is a 6% overall darkening of the artwork
   display:none on the pseudo-element beats the shared
.bento-card:hover:not(.bento-featured) .bento-media::after{opacity:1}
   outright, and filter:none at (1,2,1) beats the shared hover filter at
   (0,3,1), so neither comes back on hover. The hover zoom, scale(1.04), is a
   transform and is untouched.

   .bento-media{background:#050505} is left in place: the img is object-fit:
   cover at 100% x 100%, so the near-black backdrop is never actually visible
   and removing it would change nothing on screen.

   Scoped to these two class names, both of which appear on index.html only, so
   the same vignette and filter still apply to the image cards on
   digital-marketing.html (.bento-svc-img1/2, .bento-wd-img). */
#services-preview .bento-dm .bento-media::after,
#services-preview .bento-support .bento-media::after{display:none}
/* Image cards are static artwork — no hover lift, glow, zoom, or click press. */
#services-preview .bento-dm:hover,
#services-preview .bento-support:hover,
#services-preview .bento-dm:active,
#services-preview .bento-support:active{transform:none;box-shadow:none;border-color:rgba(255,255,255,0.10)}
#services-preview .bento-dm:hover .bento-media img,
#services-preview .bento-support:hover .bento-media img{transform:none}
#services-preview .bento-dm .bento-media img,
#services-preview .bento-support .bento-media img{filter:none}

.bento-grid{
  display:grid;
  grid-template-columns:17fr 22fr 14fr;
  grid-template-rows:290px 290px 180px;
  grid-template-areas:
    "feat  cons  cons"
    "vis   dm    supp"
    "gth   gth   gth";
  gap:22px;
}
.bento-card{
  position:relative;display:flex;flex-direction:column;
  background:#111111;
  border:1px solid rgba(255,255,255,0.10);
  border-radius:20px;overflow:hidden;
  transition:transform .38s ease,border-color .38s ease,box-shadow .38s ease;
}
/* hover — red glow rising from the top edge (content cards only, not the two image cards) */
.bento-card:not(.bento-dm):not(.bento-support)::before{
  content:'';position:absolute;inset:-20%;z-index:3;

  background:linear-gradient(105deg,transparent 42%,rgba(255,255,255,0.14) 50%,transparent 58%);

  transform:translateX(-120%);
  transition:transform .7s cubic-bezier(.22,.61,.36,1);
  pointer-events:none;
}
.bento-card:not(.bento-dm):not(.bento-support)::after{
  content:'';position:absolute;top:0;left:0;right:0;height:55%;z-index:2;
  background:radial-gradient(120% 100% at 50% 0%,rgba(225,38,28,0.22),rgba(225,38,28,0) 70%);
  opacity:0;transition:opacity .32s ease;pointer-events:none;
}
.bento-card:hover{
  transform:translateY(-4px);
  border-color:rgba(225,38,28,0.55);
  box-shadow:0 24px 50px -24px rgba(225,38,28,0.45),0 18px 40px -20px rgba(0,0,0,0.8);
}
.bento-card:not(.bento-dm):not(.bento-support):hover{
  box-shadow:0 24px 50px -24px rgba(225,38,28,0.45),0 18px 40px -20px rgba(0,0,0,0.8),0 -8px 34px -10px rgba(225,38,28,0.55);
}
.bento-card:not(.bento-dm):not(.bento-support):hover::before{transform:translateX(120%)}
.bento-card:not(.bento-dm):not(.bento-support):hover::after{opacity:1}
/* click feedback — physical press-down on mouse/touch press */
.bento-card:active{transform:translateY(-1px) scale(0.985);transition-duration:.12s}
@media(prefers-reduced-motion:reduce){
  .bento-card:not(.bento-dm):not(.bento-support)::before{transition:none;transform:none}
  .bento-card:active{transform:none}
}
.bento-media{
  position:relative;overflow:hidden;isolation:isolate;
  background:#050505;
}
/* imagery is static — no hover zoom or grade shift on any image card */
.bento-media img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.88) contrast(1.04) brightness(.94);
}
.bento-card:hover .bento-media img{transform:none;filter:saturate(.88) contrast(1.04) brightness(.94)}

/* neutral vignette (black, not red) so the photo melts into the card edge */
.bento-card:not(.bento-featured) .bento-media{flex:1;min-height:210px}
.bento-media::after{
  content:'';position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    radial-gradient(120% 100% at 50% 50%,rgba(0,0,0,0) 55%,rgba(0,0,0,0.45) 100%),
    linear-gradient(180deg,rgba(0,0,0,0.12) 0%,rgba(0,0,0,0) 30%,rgba(0,0,0,0.28) 100%);
}
/* vignette stays put — no fade on hover */
.bento-card:hover:not(.bento-featured) .bento-media::after{opacity:1}

/* featured card — primary content card */
.bento-featured{grid-area:feat}
.bento-featured .bento-body{padding:30px 32px 34px}
.bento-featured .bento-body h3{font-size:1.6rem}

/* secondary service content card (background image removed) */
.bento-visual{grid-area:dm}
.bento-visual .bento-body{padding:30px 32px 34px}
.bento-visual .bento-body h3{font-size:1.5rem}

/* content cards — generous negative space, no imagery */
.bento-consulting{grid-area:supp}
.bento-dm{
  grid-area:vis;
}
.bento-dm .bento-media{position:absolute;inset:0}
.bento-support{
  grid-area:cons;
}
.bento-support .bento-media{position:absolute;inset:0}
.bento-consulting .bento-body{padding:30px 32px 34px}

/* wide band card — text laid out horizontally so the full-width row reads well */
.bento-growth{grid-area:gth}
.bento-growth .bento-body{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.15fr) auto;
  grid-template-areas:
    "tag p cta"
    "h3  p cta";
  align-items:center;
  column-gap:34px;
  padding:30px 32px 34px;
}
.bento-growth .bento-tag{grid-area:tag;align-self:end;margin-bottom:2px}
.bento-growth .bento-body h3{grid-area:h3;align-self:start;margin-bottom:0}
.bento-growth .bento-body p{grid-area:p}
.bento-growth .bento-cta{grid-area:cta;margin-top:0;white-space:nowrap}

.bento-body{padding:26px 28px 30px;display:flex;flex-direction:column;flex:1;position:relative;z-index:4}
.bento-tag{
  display:block;font-family:var(--mono);font-size:0.68rem;font-weight:600;
  letter-spacing:0.16em;text-transform:uppercase;color:#FF2B22;margin-bottom:14px;
}
.bento-body h3{font-size:1.4rem;font-weight:700;color:var(--n-0);letter-spacing:-0.01em;margin-bottom:10px}
.bento-body p{font-size:0.93rem;line-height:1.7;color:#B5B5B5;flex:1}
.bento-cta{
  display:inline-flex;align-items:center;gap:8px;margin-top:22px;
  font-size:0.85rem;font-weight:600;color:var(--n-0);
  border:1px solid rgba(255,255,255,0.22);border-radius:999px;padding:8px 14px;
  transition:background .3s ease,color .3s ease,border-color .3s ease;
}
.bento-cta .arw{display:inline-block;transition:transform .3s ease}
.bento-card:hover .bento-cta{background:var(--red-500);border-color:transparent;color:#fff}
.bento-card:hover .bento-cta .arw{transform:translateX(4px)}

/* tablet — reorganize while preserving the hierarchy */
@media(max-width:980px){
  .bento-grid{
    grid-template-columns:1.3fr 1fr;
    grid-template-rows:300px minmax(260px,auto) minmax(190px,auto) minmax(240px,auto);
    grid-template-areas:
      "feat  feat"
      "vis   cons"
      "dm    supp"
      "gth   gth";
  }
  /* stacked body again once the band is no longer wide */
  .bento-growth .bento-body{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:"tag" "h3" "p" "cta";
    align-items:start;
    column-gap:0;
  }
  .bento-growth .bento-tag{margin-bottom:14px}
  .bento-growth .bento-body h3{margin-bottom:10px}
  .bento-growth .bento-cta{margin-top:22px}
}
/* mobile: stack — featured first, hierarchy preserved */
@media(max-width:640px){
  .bento-grid{
    grid-template-columns:1fr;
    grid-template-rows:none;
    grid-template-areas:
      "feat"
      "vis"
      "cons"
      "dm"
      "supp"
      "gth";
    gap:18px;
  }
  .bento-featured{min-height:280px}
  .bento-visual{min-height:280px}
  .bento-support{min-height:260px}
  .bento-dm{min-height:260px}
  .bento-growth{min-height:240px}
  .bento-featured .bento-body{padding:30px 26px}
  .bento-featured .bento-body h3{font-size:1.7rem}
  .bento-body{padding:24px 24px 28px}
}

/* Bento grid for the digital-marketing services band.
   Same card chrome as index.html's "Our services" (.bento-card is shared);
   this only re-places the cells so the six services + two image cards fit.
   6 service cards: s1 s2 s3 s4 s5 s6 · 2 image cards: i1 (wide) i2
   Rows and type are deliberately tighter than the base .bento-grid: eight
   cards at the inherited 290/290/250 made the band 874px tall, which pushed
   the rest of the page a long way down. Everything here is scaled to keep
   the same content at roughly three quarters of the height. */
.bento-grid--svc{
  grid-template-columns:17fr 22fr 14fr;
  grid-template-rows:242px 206px 190px;
  grid-template-areas:
    "s1  i1  i1"
    "s2  s3  s4"
    "s5  s6  i2";
  gap:16px;
}
.bento-svc-1{grid-area:s1}
.bento-svc-2{grid-area:s2}
.bento-svc-3{grid-area:s3}
.bento-svc-4{grid-area:s4}
.bento-svc-5{grid-area:s5}
.bento-svc-6{grid-area:s6}
.bento-svc-img1{grid-area:i1}
.bento-svc-img2{grid-area:i2}
/* the two image cards opt out of the red hover treatment, exactly like
   .bento-dm / .bento-support on index.html */
.bento-svc-img1,.bento-svc-img2{position:relative;display:flex;flex-direction:column}
.bento-svc-img1 .bento-media,.bento-svc-img2 .bento-media{position:absolute;inset:0}
.bento-card.bento-svc-img1::before,
.bento-card.bento-svc-img1::after,
.bento-card.bento-svc-img2::before,
.bento-card.bento-svc-img2::after{display:none}
/* digital-marketing.html image cards are static artwork — no hover lift,
   glow, zoom, or click press. */
.bento-card.bento-svc-img1:hover,.bento-card.bento-svc-img1:active,
.bento-card.bento-svc-img2:hover,.bento-card.bento-svc-img2:active,
.bento-card.bento-wd-img:hover,.bento-card.bento-wd-img:active{transform:none;box-shadow:none}
.bento-card.bento-svc-img1:hover .bento-media img,
.bento-card.bento-svc-img2:hover .bento-media img,
.bento-card.bento-wd-img:hover .bento-media img{transform:none;filter:none}
/* the lead card keeps a size lead, mirroring .bento-featured */
.bento-svc-1 .bento-body{padding:20px 24px 22px}
.bento-svc-1 .bento-body h3{font-size:1.24rem}
.bento-svc-2 .bento-body,
.bento-svc-3 .bento-body,
.bento-svc-4 .bento-body,
.bento-svc-5 .bento-body,
.bento-svc-6 .bento-body{padding:18px 20px 20px}
.bento-svc-2 .bento-body h3,
.bento-svc-3 .bento-body h3{font-size:1.08rem}
.bento-svc-4 .bento-body h3,
.bento-svc-5 .bento-body h3,
.bento-svc-6 .bento-body h3{font-size:1rem}
/* tighter tag + copy + CTA rhythm to match the shorter rows */
.bento-svc-1 .bento-tag,
.bento-svc-2 .bento-tag,
.bento-svc-3 .bento-tag,
.bento-svc-4 .bento-tag,
.bento-svc-5 .bento-tag,
.bento-svc-6 .bento-tag{font-size:.62rem;letter-spacing:.14em;margin-bottom:9px}
.bento-svc-1 .bento-body h3,
.bento-svc-2 .bento-body h3,
.bento-svc-3 .bento-body h3,
.bento-svc-4 .bento-body h3,
.bento-svc-5 .bento-body h3,
.bento-svc-6 .bento-body h3{margin-bottom:6px}
.bento-svc-1 .bento-body p,
.bento-svc-2 .bento-body p,
.bento-svc-3 .bento-body p,
.bento-svc-4 .bento-body p,
.bento-svc-5 .bento-body p,
.bento-svc-6 .bento-body p{font-size:.8rem;line-height:1.55}
.bento-svc-1 .bento-cta,
.bento-svc-2 .bento-cta,
.bento-svc-3 .bento-cta,
.bento-svc-4 .bento-cta,
.bento-svc-5 .bento-cta,
.bento-svc-6 .bento-cta{font-size:.78rem;margin-top:12px;gap:6px}

@media(max-width:980px){
  .bento-grid--svc{
    grid-template-columns:1fr 1fr;
    grid-template-rows:230px minmax(200px,auto) minmax(200px,auto) minmax(200px,auto) minmax(200px,auto);
    grid-template-areas:
      "s1   s1"
      "s2   s3"
      "s4   s5"
      "s6   i1"
      "i2   i2";
    gap:16px;
  }
  .bento-svc-img1,.bento-svc-img2{min-height:210px}
}
@media(max-width:640px){
  .bento-grid--svc{
    grid-template-columns:1fr;
    grid-template-rows:none;
    grid-template-areas:"s1" "i1" "s2" "s3" "s4" "s5" "s6" "i2";
    gap:14px;
  }
  .bento-svc-1,.bento-svc-2,.bento-svc-3,.bento-svc-4,.bento-svc-5,.bento-svc-6{min-height:0}
  .bento-svc-1 .bento-body,.bento-svc-2 .bento-body,.bento-svc-3 .bento-body,
  .bento-svc-4 .bento-body,.bento-svc-5 .bento-body,.bento-svc-6 .bento-body{padding:20px 20px 22px}
  .bento-svc-1 .bento-body h3,
  .bento-svc-2 .bento-body h3,
  .bento-svc-3 .bento-body h3,
  .bento-svc-4 .bento-body h3,
  .bento-svc-5 .bento-body h3,
  .bento-svc-6 .bento-body h3{font-size:1.14rem;margin-bottom:8px}
  .bento-svc-1 .bento-body p,.bento-svc-2 .bento-body p,.bento-svc-3 .bento-body p,
  .bento-svc-4 .bento-body p,.bento-svc-5 .bento-body p,.bento-svc-6 .bento-body p{font-size:.88rem;line-height:1.6}
  .bento-svc-img1,.bento-svc-img2{min-height:190px}
}

/* Bento grid for the Web Design band (digital-marketing.html).
   Same .bento-card chrome again; this is a 3-card + 1-image shape.
   Declared after the base .bento-grid media queries on purpose - they have
   identical specificity, so source order is what makes these win.
   3 design cards: w1 w2 w3 · 1 image card: wi
   Row heights and type are scaled to match .bento-grid--svc. */
.bento-grid--wd{
  grid-template-columns:17fr 22fr 14fr;
  grid-template-rows:242px 206px;
  grid-template-areas:
    "w1  wi  wi"
    "w2  w2  w3";
  gap:16px;
}
.bento-wd-1{grid-area:w1}
.bento-wd-2{grid-area:w2}
.bento-wd-3{grid-area:w3}
.bento-wd-img{grid-area:wi}
/* image card opts out of the red hover treatment, as on index.html */
.bento-wd-img{position:relative;display:flex;flex-direction:column}
.bento-wd-img .bento-media{position:absolute;inset:0}
.bento-card.bento-wd-img::before,
.bento-card.bento-wd-img::after{display:none}
/* same compact scale as .bento-grid--svc */
.bento-wd-1 .bento-body{padding:20px 24px 22px}
.bento-wd-1 .bento-body h3{font-size:1.24rem}
.bento-wd-2 .bento-body,
.bento-wd-3 .bento-body{padding:18px 20px 20px}
.bento-wd-2 .bento-body h3,
.bento-wd-3 .bento-body h3{font-size:1.06rem}
.bento-wd-1 .bento-tag,
.bento-wd-2 .bento-tag,
.bento-wd-3 .bento-tag{font-size:.62rem;letter-spacing:.14em;margin-bottom:9px}
.bento-wd-1 .bento-body h3,
.bento-wd-2 .bento-body h3,
.bento-wd-3 .bento-body h3{margin-bottom:6px}
.bento-wd-1 .bento-body p,
.bento-wd-2 .bento-body p,
.bento-wd-3 .bento-body p{font-size:.8rem;line-height:1.55}
.bento-wd-1 .bento-cta,
.bento-wd-2 .bento-cta,
.bento-wd-3 .bento-cta{font-size:.78rem;margin-top:12px;gap:6px}

/* "03 / System" (Design Systems) given the same brand-red fill as the red
   cards on index.html. Scoped to #web-design - the id is unique to this
   section - so it cannot follow the element onto another page.

   The copy flips with the fill, exactly as on index: measured against
   #D71920, .bento-tag #FF2B22 is 1.37:1 (red on red) and the body #B5B5B5 is
   2.49:1, both failing. h3 and .bento-cta are already white at 5.11:1. So the
   tag and the paragraph go white, and hierarchy rests on size and weight - the
   tag is .62rem mono uppercase, the h3 is bold.

   Border is white here, NOT the black used on the index cards, because this
   section is a dark artwork band (dm-band-art + scrim) rather than a white
   one. A black hairline would sit between a red card and a near-black ground
   and define nothing; rgba(255,255,255,.34) traces the edge from the dark
   side instead. The card hover is pinned off the shared rgba(225,38,28,.55),
   which is red on a red fill and therefore invisible.

   The CTA pill needs more than a colour pin, and this is where the red cards
   on index already had to diverge. .bento-cta is a bordered pill that the
   shared hover fills with var(--red-500). On a black card that reads as an
   accent; on this red card it would be a red pill on a red fill with its
   border set to transparent - the whole affordance would disappear under the
   pointer. So the pill follows the index treatment exactly: resting border
   raised to rgba(255,255,255,.5), hover filled #0B0B0C so it reads as a dark
   pill against the red. Text stays white at 5.19:1 either way; the .arw still
   slides. */
#web-design .bento-wd-3{background:var(--red-500);border-color:rgba(255,255,255,0.34)}
#web-design .bento-wd-3 .bento-tag{color:var(--n-0)}
#web-design .bento-wd-3 .bento-body p{color:var(--n-0)}
#web-design .bento-wd-3:hover{border-color:rgba(255,255,255,0.72)}
#web-design .bento-wd-3 .bento-cta{border-color:rgba(255,255,255,0.5)}
#web-design .bento-wd-3:hover .bento-cta{background:#0B0B0C;border-color:transparent;color:var(--n-0)}

/* Two cards in "Digital marketing services" given the same fill: SEO
   (.bento-svc-1, the wide lead card) and Conversion Optimization
   (.bento-svc-5). They are the top and bottom of the left-hand column with
   Paid Advertising between them, so the column reads red / dark / red. Only
   two of the six were asked for, so the other four stay #111111.

   Scoped to #services - unique to this section - so the red cannot follow the
   element onto another page.

   Copy flips with the fill, same as every other red card: against #D71920 the
   .bento-tag #FF2B22 is 1.37:1 and the body #B5B5B5 is 2.49:1, both failing,
   so tag and paragraph go white at 5.19:1. h3 and the CTA label are already
   white.

   Borders are BLACK here, unlike #web-design above, because this section is a
   light band (dm-band over the white bento artwork) rather than a dark one.
   Same reasoning as the red cards on index.html: #0B0B0C on the light band is
   19.67:1, so the frame reads; a white hairline would not. The card hover is
   held on black too, since the shared rgba(225,38,28,.55) is red on red.

   The CTA pill gets the same black-pill-on-hover treatment, for the same
   reason: .bento-cta is a bordered pill that the shared hover fills with
   var(--red-500), which on a red card would erase the affordance. */
#services .bento-svc-1,
#services .bento-svc-5{background:var(--red-500);border-color:#0B0B0C}
#services .bento-svc-1 .bento-tag,
#services .bento-svc-5 .bento-tag{color:var(--n-0)}
#services .bento-svc-1 .bento-body p,
#services .bento-svc-5 .bento-body p{color:var(--n-0)}
#services .bento-svc-1 .bento-cta,
#services .bento-svc-5 .bento-cta{border-color:rgba(255,255,255,0.5)}
#services .bento-svc-1:hover,
#services .bento-svc-5:hover{border-color:#0B0B0C}
#services .bento-svc-1:hover .bento-cta,
#services .bento-svc-5:hover .bento-cta{background:#0B0B0C;border-color:transparent;color:var(--n-0)}

@media(max-width:980px){
  .bento-grid--wd{
    grid-template-columns:1fr 1fr;
    grid-template-rows:230px minmax(200px,auto) minmax(200px,auto);
    grid-template-areas:
      "w1  w1"
      "w2  wi"
      "w3  w3";
    gap:16px;
  }
  .bento-wd-img{min-height:210px}
}
@media(max-width:640px){
  .bento-grid--wd{
    grid-template-columns:1fr;
    grid-template-rows:none;
    grid-template-areas:"w1" "wi" "w2" "w3";
    gap:14px;
  }
  .bento-wd-1,.bento-wd-2,.bento-wd-3{min-height:0}
  .bento-wd-1 .bento-body,.bento-wd-2 .bento-body,.bento-wd-3 .bento-body{padding:20px 20px 22px}
  .bento-wd-1 .bento-body h3,
  .bento-wd-2 .bento-body h3,
  .bento-wd-3 .bento-body h3{font-size:1.14rem;margin-bottom:8px}
  .bento-wd-1 .bento-body p,.bento-wd-2 .bento-body p,.bento-wd-3 .bento-body p{font-size:.88rem;line-height:1.6}
  .bento-wd-img{min-height:190px}
}


/* ---- Process / how we work ---- */
.process{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;list-style:none;counter-reset:step}
.step{position:relative;padding-top:30px;border-top:2px solid var(--line);transition:border-color .3s}
.step::before{
  content:'';position:absolute;top:-7px;left:0;width:12px;height:12px;border-radius:50%;
  background:var(--bg);border:2px solid var(--accent);transition:all .3s;
}
.step:hover{border-top-color:var(--accent)}
.step:hover::before{background:var(--accent);box-shadow:0 0 0 5px rgba(215,25,32,0.18)}
.step .step-n{font-family:var(--mono);font-size:0.7rem;font-weight:600;letter-spacing:0.14em;color:var(--accent-ink);display:block;margin-bottom:10px}
.step h3{margin-bottom:9px}
.step p{font-size:0.9rem;line-height:1.65}
@media(max-width:860px){.process{grid-template-columns:1fr 1fr;gap:30px 22px}}
@media(max-width:520px){.process{grid-template-columns:1fr}}
/* explicit column counts (higher specificity so it wins over the breakpoints above) */
.process.cols-3{grid-template-columns:repeat(3,1fr)}
@media(max-width:860px){.process.cols-3{grid-template-columns:1fr}}


/* ---- About operation media ---- */
.operation-media{
  position:relative;border-radius:var(--r-lg);overflow:hidden;
  background:var(--bg2);border:1px solid var(--line);
  box-shadow:var(--shadow-lg);aspect-ratio:16/9;
}
.operation-media img{width:100%;height:100%;object-fit:cover;display:block}
.operation-media:hover img{transform:none}

/* ---- Why businesses trust us ---- */
/* Section background artwork, authored at 1440 x 838 (the measured height of
   this section at 1440px viewport). Kept as a CSS background rather than an
   <img> so it sits behind the cards instead of taking layout space.
   Source of truth: assets/bento/background_1440x838.webp (28 KB).
   cover + center so it absorbs the content-driven height changes at other
   breakpoints (this section measures 1223px tall at 768 and 1487px at 375). */
#why-trust-us{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
.trust-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;align-items:stretch}
.trust-card{position:relative;display:flex;flex-direction:column;background:linear-gradient(180deg,#17171A 0%,#0B0B0C 100%);border:1px solid #26262B;border-radius:18px;padding:30px 28px 28px;overflow:hidden;box-shadow:0 18px 36px -22px rgba(11,11,12,0.7);transition:transform .3s ease,box-shadow .3s ease,border-color .3s ease}
.trust-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--red-500) 0%,var(--red-400) 100%);transform:scaleX(1);transform-origin:left;opacity:.85}
@media(prefers-reduced-motion:reduce){.trust-card{transition:none}}
.trust-card:hover{transform:translateY(-4px);border-color:rgba(225,38,28,0.55);box-shadow:0 26px 52px -20px rgba(0,0,0,0.75),0 0 0 1px rgba(225,38,28,0.16),0 0 28px -6px rgba(225,38,28,0.35)}
.trust-n{display:flex;align-items:center;gap:12px;font-family:var(--mono);font-size:0.68rem;font-weight:600;letter-spacing:0.14em;color:#FF5147;margin-bottom:14px}
.trust-n::after{content:'';height:1px;flex:1;background:rgba(255,255,255,0.14)}
.trust-card h3{font-size:1.15rem;font-weight:700;color:var(--n-0);letter-spacing:-0.01em;margin:0 0 10px;line-height:1.3}
.trust-card p{font-size:0.92rem;line-height:1.7;color:#B9B9C0;margin:0}
.trust-card.lead{background:linear-gradient(180deg,#17171A 0%,#0B0B0C 100%);border-color:#26262B}
.trust-card.lead .trust-n{color:#FF5147}
.trust-card.lead .trust-n::after{background:rgba(255,255,255,0.14)}
.trust-card.lead h3{color:var(--n-0)}
.trust-card.lead p{color:#B9B9C0}
/* Outrank .u-border-black / .u-border-red utilities (0,2,0) so every card
   in this grid keeps the premium dark hairline on the light band. */
#why-trust-us .trust-card{border-color:#26262B}
#why-trust-us .trust-card:hover{border-color:rgba(225,38,28,0.55)}
@media(max-width:960px){.trust-grid{grid-template-columns:1fr 1fr;gap:18px}.trust-card.lead{grid-column:1/-1}}
@media(max-width:620px){.trust-grid{grid-template-columns:1fr;gap:14px}.trust-card.lead{grid-column:1}.trust-card{padding:28px 22px}}

/* ---- Values / feature cards (about, career) ---- */
/* Background artwork on the 'Core values' section (about.html).
   Same shared asset as the other four sections: 28 KB, one cached fetch.
   Art is 1440 x 838, this section is 1440 x 515, so `cover` renders 1:1
   and crops ~161px off the top and bottom. No upscaling.
   Note: the .val-card-flat cards are opaque #FFFFFF, so the artwork only
   reads in the header band, the 172px side gutters and the 20px grid gaps. */
#core-values{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
.values-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.val-card{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  padding:32px 28px;
  position:relative;overflow:hidden;
  box-shadow:var(--shadow-sm);
  transition:all .3s ease;
}
.val-card:hover{border-color:var(--accent);background:var(--card-hover);transform:translateY(-4px);box-shadow:0 16px 36px -18px rgba(215,25,32,0.45)}
.val-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--grad);opacity:0;transition:opacity .3s}
.val-card:hover::before{opacity:1}
.val-card h3{margin-bottom:8px}
/* #5 contact.html: .panel-title headings are h2 for correct outline order.
   These replicate the h3 metrics exactly so rendering is unchanged. */
.panel-title h2{font-size:clamp(1.05rem,1.4vw,1.2rem);font-weight:600;
  letter-spacing:-0.015em;line-height:1.3;color:var(--ink);font-family:'Inter',sans-serif}
.val-card p{font-size:0.9rem}
@media(max-width:760px){.values-grid{grid-template-columns:1fr}}

/* Background artwork on the 'Why join us' section (career.html).
   Same shared asset as the other five sections: 28 KB, one cached fetch.
   Art is 1440 x 838; this section is 1440 x 438, so `cover` renders 1:1
   and crops ~200px off the top and bottom - the most aggressive crop so far.
   The .val-card cards are opaque #FFFFFF and fill 96% of the grid, so the
   artwork reads in the header band, the 172px gutters and the 20px gaps. */
#why-join{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}

/* ---- Flat static value cards: no hover / motion, black border with a red
   left rail. Shared by "Core values" (about.html) and "Why join us"
   (career.html). Typography is intentionally NOT shared. ---- */
.val-card-flat,
.why-join .val-card{
  background:var(--n-0);
  border:1px solid #0B0B0C;
  border-left:3px solid var(--red-500);
  border-radius:var(--r-lg);
  padding:34px 30px 32px;
  position:relative;
  box-shadow:none;
  transition:none;
}
.val-card-flat::before,
.why-join .val-card::before{display:none}
.val-card-flat:hover,
.why-join .val-card:hover{
  border-color:#0B0B0C;
  border-left-color:var(--red-500);
  background:var(--n-0);
  transform:none;
  box-shadow:none;
}
.why-join .val-card h3{
  margin:0 0 10px;
  font-size:1.06rem;
  font-weight:700;
  letter-spacing:-0.015em;
  line-height:1.3;
  color:var(--n-950);
}
.why-join .val-card p{
  margin:0;
  font-size:0.92rem;
  line-height:1.65;
  color:var(--n-700);
}
@media(max-width:760px){
  .why-join .val-card{padding:28px 24px}
}


/* ---- Story image (about) ---- */
/* Background artwork on the 'Our story' section (about.html).
   Source: assets/bento/background_1440x838.webp (28 KB) - the same single
   asset used by the other six textured sections (#why-trust-us,
   .services-preview, #faq, #core-values, #why-join, #lets-connect), so
   the browser fetches it once and reuses it from cache.
   The art is 1440 x 838; this section measures 1440 x 590 at a 1440px
   viewport, so `cover` renders 1:1 and crops ~124px off the top and
   bottom. No upscaling. */
#our-story{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
/* max-width:100% is load-bearing, not cosmetic. As a grid item, .story-img had
   an automatic minimum size (min-width:auto) driven by the <img>'s intrinsic
   1448px width, so the 1fr track could never shrink below it and the whole
   grid overflowed the viewport. That produced 31-230px of horizontal scroll
   on about.html between roughly 860px and 1090px wide - every width where the
   container is narrower than the image's intrinsic size. Capping the box at
   the track width lets the track resolve, and the image inside already has
   object-fit:cover so it crops instead of overflowing. */
.story-img{position:relative;border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/3;background:var(--bg2);border:1px solid var(--line);box-shadow:var(--shadow);max-width:100%}
.story-img img{width:100%;height:100%;object-fit:cover}
.story-img:hover img{transform:none}
/* The "Our story" artwork is assets/about/02.webp, 1000x750 (4:3),
   matching the .story-img box above, so no cropping override is needed.

   align-self:start is the load-bearing half, and it is the grid equivalent of
   the flex:0 0 auto that .apply-left .story-img uses on career.html. This card
   is a direct child of .split, which is display:grid with align-items:stretch,
   so without it the card's height is set by the taller text column beside it and
   aspect-ratio is ignored - that is what produced the worst case, a 385x479
   portrait card at 885px wide that threw away 46% of the illustration. In grid,
   align-self is the BLOCK axis (vertical, because .split sets grid-template-
   columns), so start is what stops the vertical stretch.

   Scoped to .split > .story-img because .story-img itself is shared: career.html
   uses the same class inside .apply-left, where align-self would control the
   HORIZONTAL axis of a column flex container and shrink the card to its content
   width. career.html keeps its own .apply-left .story-img rule and is unaffected. */
.split > .story-img{align-self:start;aspect-ratio:4/3}
.story-img .img-label{
  position:absolute;bottom:16px;left:16px;z-index:2;
  font-family:var(--mono);font-size:0.65rem;font-weight:500;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--on-dark);
  background:rgba(8,8,8,0.76);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  padding:8px 14px;border-radius:8px;
}

/* Background artwork on the 'Let's connect' section (contact.html).
   Same single asset as the other textured sections (28 KB, one cached fetch).
   The art is 1440 x 838 and this section measures 1440 x 815 at a 1440px
   viewport, so `cover` renders it 1:1 with a ~12px crop - no upscaling.
   Inside, the .split is 1160 x 647: a white .contact-info-card (shadowed) and
   the dark #080808 .contact-form, 52px apart. Panels cover 90% of that grid
   but only 58% of the section, so the artwork reads in the 140px side
   gutters, the 64px/104px vertical padding and the 52px centre gap. */
#lets-connect{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
/* #lets-connect only: stop .split stretching the two panels to a common height.
   The form is ~647px tall and the contact card's content is ~325px, so
   align-items:stretch left 308-330px of blank white under the last info row -
   the card was half empty at every desktop width (measured: content filled
   50-52% of its own box). Each panel now takes its own height.

   Scoped to #lets-connect on purpose. The shared .split still stretches
   elsewhere and NEEDS to: career.html's .apply-left column is balanced against
   the application form by that stretch, and removing it there would leave that
   column short. */
#lets-connect .split{align-items:start}

/* Panel titles here were 16.8px (19.2px at 1440), inherited from .panel-title
   h2 - which is sized to match the h3s these replaced for outline order. Too
   small to name a 647px panel. Lifted to 21.6-27.2px, still clearly a panel
   title rather than the 28-40px section h2. Scoped so digital-marketing.html's
   "Start a project", the third user of .panel-title h2, is untouched.

   Colour is unchanged: var(--ink) is dark on the white card, and .contact-form
   redefines --ink to white, so both keep their existing contrast. */
#lets-connect .panel-title h2{
  font-size:clamp(1.35rem,2.2vw,1.7rem);
  line-height:1.2;
}
#lets-connect .panel-title{margin-bottom:10px}

/* ---- Panels & forms (contact, career) ---- */
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding:38px 34px;box-shadow:var(--shadow-sm)}
.contact-form{
  --bg2:var(--n-950);--card:var(--n-900);--card-hover:#1C1C1C;
  --ink:var(--n-0);--dim:var(--n-400);--faint:var(--n-500);
  --accent-ink:var(--red-300);
  --line:rgba(255,255,255,0.16);
  background:var(--n-1000);color:var(--dim);border-color:var(--line);
}
.contact-form .field input,.contact-form .field select,.contact-form .field textarea{background:var(--card);color:var(--ink);border-color:var(--line)}
.contact-form .field input::placeholder,.contact-form .field textarea::placeholder{color:var(--faint)}
.contact-form .field select option{background:var(--bg2);color:var(--ink)}
.contact-info-card{border-color:var(--accent)}
.panel-title{display:flex;align-items:center;gap:12px;margin-bottom:6px}
.panel-title::before{content:'';width:26px;height:2px;background:var(--accent);border-radius:2px}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:20px}
.field{display:flex;flex-direction:column;gap:6px}
.field.full{grid-column:1/-1}
.field label{font-size:0.78rem;font-weight:600;color:var(--ink);letter-spacing:-0.01em}
.field label em{font-style:normal;color:var(--accent-ink)}
.field input,.field select,.field textarea{
  width:100%;padding:13px 14px;
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--r);
  color:var(--ink);
  font-family:'Inter',sans-serif;font-size:0.94rem;
  transition:all .2s;outline:none;
}
.field input::placeholder,.field textarea::placeholder{color:var(--faint)}
.field select{color:var(--dim);cursor:pointer}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--accent-ink);
  box-shadow:0 0 0 3px rgba(215,25,32,0.28);
}
.field textarea{min-height:128px;resize:vertical}
.field select option{background:var(--bg2);color:var(--ink)}
.phone-field{display:flex;gap:10px}
.phone-field select{flex:0 0 180px}
.form-submit{
  margin-top:6px;width:100%;padding:16px;
  border:none;border-radius:var(--r);
  background:var(--brand);color:var(--on-dark);
  font-weight:600;font-size:0.94rem;font-family:'Inter',sans-serif;
  cursor:pointer;transition:all .25s;
}
.form-submit:hover{background:var(--red-400);color:#fff;transform:translateY(-2px);box-shadow:0 14px 30px -12px rgba(215,25,32,0.55)}
/* Set by contact-form.js / career-form.js for the 3s window after a submit,
   so a second click cannot fire a duplicate mailto: navigation. Needs its own
   rule because :hover would otherwise lift and brighten a disabled button. */
.form-submit:disabled{
  cursor:default;opacity:.72;transform:none;box-shadow:none;
  background:var(--brand);color:var(--on-dark);
}
.form-foot{font-size:0.78rem;color:var(--faint);text-align:center;margin-top:14px}
.file-row{display:flex;gap:10px;align-items:center;position:relative}
.file-row input[type="file"]{
  position:absolute;opacity:0;width:1px;height:1px;padding:0;
  border:0;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;white-space:nowrap;
}
.file-row .file-btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:11px 16px;border-radius:var(--r);
  border:1px dashed var(--line);
  background:var(--bg2);color:var(--dim);
  font-size:0.85rem;font-weight:600;cursor:pointer;white-space:nowrap;
  transition:all .2s;
}
.file-row .file-btn:hover{border-color:var(--accent-ink);color:var(--accent-ink);background:var(--accent-soft)}
.file-row input[type="file"]:focus-visible + .file-btn{outline:2px solid var(--accent-ink);outline-offset:2px}
.file-remove{
  padding:10px 14px;border-radius:var(--r);
  border:1px solid var(--line);
  background:var(--card-hover);color:var(--dim);
  font-size:0.78rem;font-weight:600;cursor:pointer;white-space:nowrap;
  transition:all .2s;
  display:none; /* only appears once a file is actually chosen */
}
.file-row.has-file .file-remove{display:inline-block}
.file-remove:hover{border-color:var(--accent-ink);color:var(--accent-ink)}
.file-note{font-size:0.76rem;color:var(--faint)}
.file-error{font-size:0.76rem;color:var(--danger);min-height:14px}
@media(max-width:640px){.form-grid{grid-template-columns:1fr}.phone-field{flex-direction:column}.phone-field select{flex:1}}

/* ---- Contact info list ---- */
.info-list{display:flex;flex-direction:column;gap:22px;margin:26px 0 28px}
.info-row{display:flex;gap:14px;align-items:flex-start}
.info-ic{
  width:42px;height:42px;min-width:42px;border-radius:12px;
  border:1px solid rgba(215,25,32,0.35);
  background:var(--accent-soft);
  display:flex;align-items:center;justify-content:center;
  color:var(--accent-ink);
}
.info-ic svg{stroke:currentColor;fill:none;stroke-width:1.6}
.info-row b{
  display:block;font-family:var(--mono);font-size:0.66rem;font-weight:600;letter-spacing:0.12em;
  text-transform:uppercase;color:var(--faint);margin-bottom:3px;
}
.info-row span{font-size:0.95rem;color:var(--ink)}

/* ---- Services: tabbed disciplines (services) ---- */
.svc-tabs-wrap{
  position:sticky;top:var(--hdr-h);z-index:90;
  background:linear-gradient(180deg,rgba(255,255,255,0.97),rgba(255,255,255,0.92));
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
}
/* .svc-tabs-bar is the visual 4-up row; .svc-tabs holds the three real tabs
   as its own 3-up grid so role="tablist" only ever owns role="tab" children.
   The 4th cell is .svc-tab-out, a link to digital-marketing.html. */
.svc-tabs-bar{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding:11px 0}
.svc-tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;min-width:0;grid-column:span 3}
.svc-tab{
  display:flex;align-items:center;gap:11px;text-align:left;cursor:pointer;
  padding:10px 15px;border-radius:12px;
  background:var(--n-0);border:1px solid var(--line);
  font-family:inherit;transition:all .25s ease;
}
.svc-tab:hover{border-color:rgba(215,25,32,0.4);background:var(--n-25);transform:translateY(-1px)}
.svc-tab-n{
  font-family:var(--mono);font-size:0.66rem;font-weight:600;letter-spacing:0.1em;
  /* --red-600, not --accent: this is 10.56px TEXT sitting on the red tint
     chip. --accent (#D71920) measures 4.11:1 on the composited chip tint
     (rgb(249,223,224)) and fails AA for small text; --red-600 measures
     4.79:1 on the same tint. --accent stays the FILL token. */
  color:var(--red-600);flex:none;
  width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;
  background:var(--accent-soft);border:1px solid rgba(215,25,32,0.22);
  transition:all .25s ease;
}
.svc-tab-body{display:flex;flex-direction:column;gap:2px;min-width:0}
.svc-tab-body b{font-size:0.92rem;font-weight:700;color:var(--ink);letter-spacing:-0.01em;line-height:1.2}
.svc-tab-body i{font-style:normal;font-size:0.72rem;color:var(--faint);line-height:1.3}
.svc-tab.active{
  background:linear-gradient(135deg,#1A1A1A,var(--n-950));
  border-color:rgba(225,38,28,0.55);
  box-shadow:0 14px 30px -18px rgba(0,0,0,0.55),0 0 0 1px rgba(225,38,28,0.14);
}
.svc-tab.active .svc-tab-body b{color:#fff}
.svc-tab.active .svc-tab-body i{color:rgba(255,255,255,0.62)}
.svc-tab.active .svc-tab-n{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 0 14px rgba(225,38,28,0.55)}

/* Track 04 (.svc-tab-out) is a link out to digital-marketing.html, not a
   tabpanel, so it never receives .active. It reuses .svc-tab for the chrome
   and adds a trailing arrow to signal the navigation. Title is set a shade
   smaller because "Digital Marketing & Web Design" is the longest of the four. */
.svc-tab-out{
  gap:9px;
  background:linear-gradient(180deg,var(--red-500) 0%,var(--red-600) 100%);
  border-color:transparent;
  box-shadow:inset 0 -.04em 0 rgba(0,0,0,.22);
}
.svc-tab-out:hover{background:linear-gradient(180deg,var(--red-500) 0%,var(--red-600) 100%);border-color:transparent;transform:translateY(-1px)}
.svc-tab-out .svc-tab-body b{font-size:0.86rem;line-height:1.25;color:var(--n-0)}
.svc-tab-out .svc-tab-body i{color:rgba(255,255,255,0.82)}
.svc-tab-out .svc-tab-n{background:rgba(255,255,255,0.16);border-color:rgba(255,255,255,0.35);color:#fff}
.svc-tab-go{
  margin-left:auto;flex:none;font-size:0.95rem;line-height:1;
  color:#fff;transition:color .25s ease,transform .25s ease;
}
.svc-tab-out:hover .svc-tab-go{color:#fff;transform:translateX(4px)}
.svc-tab-out:focus-visible{outline:2px solid #FF2B22;outline-offset:2px}

/* Background artwork on the service-panel band (services.html).
   Same single asset as every other textured section (28 KB, one cached fetch).
   The art is 1440 x 838 and this band measures 1440 x 791 at a 1440px
   viewport, so `cover` renders it 1:1 and crops ~47px - no upscaling.
   The three .svc-panel tabpanels are painted white by the Type A theme rule
   above, so they are made transparent here to let the band artwork through;
   .svc-card stays opaque white and hides the art behind the cards. What shows
   is the 172px side gutters, the 44px/64px padding, the 40px grid gaps and
   the h2/lede text area. Artwork is 95.8% >= 210 luminance (worst 5x5 block
   mean 216), so #0D0D0D body text keeps well over 7:1 contrast on it. */
#service-panels{
  /* Measured height of the sticky tab bar, published by services-tabs.js.
     Track 04's longer title makes the bar wrap differently at every width
     (1 line at >=1100px, 2-3 lines below that, single-line strip at <=680px),
     so the deep-link offset and the sticky aside read the real value instead
     of a hardcoded guess. 96px is the pre-measurement fallback. */
  --svc-bar-h:96px;
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
/* higher specificity than the (0,1,0) Type A rule that sets .svc-panel white */
.svc-panels .svc-panel{background:transparent}

.svc-panels{padding:44px 0 64px}
.svc-panel[hidden]{display:none}
/* deep links must clear the fixed header (--hdr-h) + sticky tab bar (--svc-bar-h) */
.svc-panel{scroll-margin-top:calc(var(--hdr-h) + var(--svc-bar-h) + 8px)}
.svc-tabs-wrap{scroll-margin-top:var(--hdr-h)}
/* keyboard focus on tabs */
.svc-tab:focus-visible{outline:2px solid #FF2B22;outline-offset:2px}
@media(prefers-reduced-motion:reduce){
  .svc-tab,.svc-tab-go,.svc-card,.svc-shot img,.svc-shot{transition:none !important}
}
.svc-panel-grid{display:grid;grid-template-columns:340px 1fr;gap:40px;align-items:start}
.svc-aside{position:sticky;top:calc(var(--hdr-h) + var(--svc-bar-h) + 12px);display:flex;flex-direction:column}
.svc-shot{
  position:relative;border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/3;
  /* Black hairline rather than var(--line). On this light panel --line is
     --n-200, a pale grey that all but disappeared next to a photograph. #0B0B0C
     is the same near-black the site's .u-border-black utility uses, so the
     frame reads as deliberate and is identical across the three panels. It
     measures about 19:1 on white, well past the 3:1 WCAG asks of a visible
     boundary. Width stays 1px - only the colour was too weak. */
  border:1px solid #0B0B0C;box-shadow:var(--shadow);background:var(--n-950);margin-bottom:20px;
}
/* The three service screenshots (incident-response / it_support / consulting)
   are shown at their natural grade. Two things were darkening them and both
   are gone:
     the img filter  was saturate(.7) contrast(1.08) brightness(.92) - 30%
                     desaturated and 8% darker overall
     the ::after     a bottom scrim, transparent to 45% then rgba(5,5,5,.75)
   Edited in place rather than overridden: .svc-shot:hover img is (0,2,1) and
   would have beaten a plain .svc-shot img override, quietly restoring the
   filter on hover. With the filter gone there is nothing left to transition,
   so `filter .5s` has come out of the transition list too; the hover zoom
   was also removed — service artwork is static with no hover/click effects.

   The ::after existed to seat the .svc-shot-tag label. That label carries its
   own near-opaque red plate - rgba(225,38,28,0.92) behind #FFFFFF text - so
   it is readable over the photograph with no scrim underneath it. The rule is
   removed rather than set to display:none because nothing else uses it.

   background:var(--n-950) on .svc-shot itself is left: the img is object-fit:
   cover at 100% x 100%, so the near-black backdrop is never visible. */
.svc-shot img{width:100%;height:100%;object-fit:cover;image-rendering:auto;content-visibility:auto}
/* Service panel artwork is static — no hover zoom or click effects. */
.svc-shot:hover img,.svc-shot:active img{transform:none}
.svc-shot-tag{
  position:absolute;left:14px;bottom:12px;z-index:2;
  font-family:var(--mono);font-size:0.62rem;letter-spacing:0.16em;text-transform:uppercase;
  /* Opaque plate, not rgba(225,38,28,.92). The 8% transparency used to let
     the ::after scrim show through and darken the red, which is what kept this
     9.92px label at about 4.6:1. With that scrim gone the label is sitting
     straight on the photograph, and over a light area the translucent red
     measured 4.31:1 - just under the 4.5 that text this small needs. Solid
     #E1261C puts it at 4.67:1 whatever is behind it, so the label no longer
     depends on the image. */
  color:#fff;background:#E1261C;padding:5px 10px;border-radius:6px;
}
.svc-aside h2{margin-bottom:12px}
.svc-aside .dim{margin-bottom:20px}
/* inline chips — threat surfaces / service commitments */
.svc-chips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 26px}
.svc-chip{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 12px 7px 10px;border-radius:999px;
  background:var(--n-50);border:1px solid var(--line);
  font-size:0.76rem;font-weight:600;letter-spacing:-0.005em;color:var(--ink);
  white-space:nowrap;transition:all .22s ease;
}
.svc-chip svg{
  width:14px;height:14px;flex:none;
  stroke:var(--accent);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;
}
.svc-chip:hover{
  background:var(--accent-soft);border-color:rgba(215,25,32,0.4);
  transform:translateY(-1px);
}
.svc-cards{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.svc-card{
  position:relative;display:flex;flex-direction:column;
  padding:24px 24px 22px;border-radius:18px;
  background:linear-gradient(180deg,#17171A 0%,#0B0B0C 100%);border:1px solid #26262B;
  transition:transform .3s ease,border-color .3s ease,box-shadow .3s ease;
  overflow:hidden;box-shadow:0 18px 36px -24px rgba(11,11,12,0.8);
}
.svc-card::before{
  content:'';position:absolute;left:0;top:0;bottom:0;width:3px;
  background:linear-gradient(180deg,var(--red-400),#FF2B22);
}
.svc-card::after{
  content:'';position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,0.14),transparent);
  pointer-events:none;
}
.svc-card:hover{
  transform:translateY(-4px);border-color:rgba(225,38,28,0.55);
  box-shadow:0 26px 52px -22px rgba(0,0,0,0.8),0 0 0 1px rgba(225,38,28,0.16),0 0 28px -8px rgba(225,38,28,0.4);
}
/* number + category chip on one row */
.svc-card-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:14px}
.svc-card-n{
  font-family:var(--mono);font-size:0.66rem;font-weight:600;letter-spacing:0.14em;
  color:#FF5147;background:rgba(225,38,28,0.12);
  border:1px solid rgba(225,38,28,0.35);border-radius:9px;padding:5px 9px;
}
.svc-tag{
  font-family:var(--mono);font-size:0.58rem;font-weight:600;letter-spacing:0.12em;
  text-transform:uppercase;color:#B9B9C0;
  border:1px solid rgba(255,255,255,0.16);border-radius:999px;padding:4px 10px;
  transition:all .25s ease;white-space:nowrap;
}
.svc-card:hover .svc-tag{color:#fff;border-color:rgba(225,38,28,0.6);background:rgba(225,38,28,0.16)}
.svc-card h3{font-size:1.05rem;font-weight:700;color:var(--n-0);letter-spacing:-0.01em;margin-bottom:8px;line-height:1.3}
.svc-card p{font-size:0.85rem;line-height:1.65;color:#B9B9C0;margin:0 0 16px;flex:1}
.svc-card-go{display:inline-flex;align-items:center;gap:8px;font-size:0.8rem;font-weight:600;color:var(--n-0);border:1px solid rgba(255,255,255,0.18);border-radius:999px;padding:7px 13px;align-self:flex-start;transition:background .25s ease,border-color .25s ease}
.svc-card-go .arw{transition:transform .25s ease}
.svc-card:hover .svc-card-go{background:var(--red-500);border-color:transparent;color:#fff}
.svc-card:hover .svc-card-go .arw{transform:translateX(4px)}
/* Keep the premium dark hairline above .u-border-black / .u-border-red utilities. */
#service-panels .svc-card{border-color:#26262B}
#service-panels .svc-card:hover{border-color:rgba(225,38,28,0.55)}
/* Red feature cards (.u-border-red): brand-red fill, white copy, black hairline. */
#service-panels .svc-card.u-border-red{background:linear-gradient(180deg,var(--red-500) 0%,var(--red-600) 100%);border-color:#0B0B0C}
#service-panels .svc-card.u-border-red:hover{border-color:#0B0B0C}
#service-panels .svc-card.u-border-red .svc-card-n{color:#fff;background:rgba(0,0,0,0.22);border-color:rgba(255,255,255,0.4)}
#service-panels .svc-card.u-border-red .svc-tag{color:#fff;border-color:rgba(255,255,255,0.5)}
#service-panels .svc-card.u-border-red:hover .svc-tag{color:#fff;border-color:rgba(255,255,255,0.7);background:rgba(0,0,0,0.18)}
#service-panels .svc-card.u-border-red h3{color:#fff}
#service-panels .svc-card.u-border-red p{color:#fff}
#service-panels .svc-card.u-border-red .svc-card-go{color:#fff;border-color:rgba(255,255,255,0.5)}
#service-panels .svc-card.u-border-red:hover .svc-card-go{background:#0B0B0C;border-color:transparent;color:#fff}
@media(prefers-reduced-motion:reduce){.svc-card{transition:none}}
@media(max-width:980px){
  .svc-tabs-wrap{top:var(--hdr-h)}
  .svc-tab-body i{display:none}
  .svc-panel-grid{grid-template-columns:1fr;gap:26px}
  /* aside becomes a side-by-side block instead of a tall stack */
  .svc-aside{position:static;display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:start}
  .svc-shot{aspect-ratio:4/3;margin-bottom:0}
  .svc-aside-body{padding-top:2px}
  .svc-aside .dim{margin-bottom:16px}
}
@media(max-width:680px){
  /* single scrollable strip instead of 4 stacked rows — saves ~150px of fixed
     chrome. The scroll container is .svc-tabs-bar; .svc-tabs drops to a plain
     flex row so its three buttons join the strip instead of nesting a scroller. */
  .svc-tabs-bar{
    display:flex;gap:8px;padding:9px 0;
    overflow-x:auto;scrollbar-width:none;scroll-snap-type:x proximity;
  }
  .svc-tabs-bar::-webkit-scrollbar{display:none}
  .svc-tabs{display:flex;gap:8px;flex:none}
  .svc-tab,.svc-tab-out{flex:0 0 auto;padding:9px 13px;scroll-snap-align:start}
  .svc-tab-n{width:26px;height:26px;font-size:0.6rem}
  .svc-tab-body b,.svc-tab-out .svc-tab-body b{font-size:0.82rem;white-space:nowrap}
  .svc-aside{grid-template-columns:1fr;gap:18px}
  .svc-shot{aspect-ratio:16/9}
  .svc-cards{grid-template-columns:1fr;gap:12px}
  .svc-panels{padding:32px 0 48px}
}

/* ---- FAQ accordion ---- */
/* Background artwork on the FAQ section. Keyed on the id, and BOTH
   services.html ("Before you ask") and contact.html ("Quick answers") carry
   <section id="faq">, so this rule paints the two of them and nothing else.
   The contact one already had this artwork before faq-cards was added there -
   the id, not the page, is what has always applied it.
   Source: assets/bento/background_1440x838.webp (28 KB) - the same single
   asset every textured section uses, so the browser fetches it once.
   The art is 1440 x 838 and this section measures 1440 x 564 at a 1440px
   viewport, so `cover` renders it 1:1 and crops ~137px off the top and
   bottom. No upscaling, unlike .services-preview which is 1026 tall. */
#faq{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
.faq{border-top:1px solid var(--line)}
.faq-item{border-bottom:1px solid var(--line)}
.faq-q{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:22px 4px;background:none;border:none;cursor:pointer;text-align:left;
  font-size:1rem;font-weight:600;color:var(--ink);letter-spacing:-0.015em;
  transition:color .2s;
}
.faq-q:hover{color:var(--accent-ink)}
.faq-ic{
  position:relative;width:26px;height:26px;min-width:26px;border-radius:50%;
  border:1px solid var(--line);transition:all .3s;
}
.faq-ic::before,.faq-ic::after{
  content:'';position:absolute;top:50%;left:50%;width:11px;height:1.6px;background:var(--ink);
  transform:translate(-50%,-50%);transition:transform .3s,background .3s;
}
.faq-ic::after{transform:translate(-50%,-50%) rotate(90deg)}
.faq-item.open .faq-ic{background:var(--accent);border-color:var(--accent);transform:rotate(180deg)}
.faq-item.open .faq-ic::after{transform:translate(-50%,-50%) rotate(0)}
.faq-a{overflow:hidden;transition:max-height .38s ease}
.js .faq-a{max-height:0}
.faq-a p{padding:0 46px 24px 4px;font-size:0.94rem}
/* Card-style FAQ variant. Each question is its own numbered card instead of a
   flush list - same markup/JS (.faq-item/.faq-q/.faq-a). Used by the
   "Before you ask" section on services.html and the "Quick answers" section
   on contact.html, which is why both carry faq-cards + faq-intro-card; the
   plain flush .faq is still what a section gets without those classes. */
.faq-cards{border-top:none;display:flex;flex-direction:column;gap:14px;counter-reset:faq}
.faq-cards .faq-item{position:relative;counter-increment:faq;border:1px solid var(--line);border-radius:16px;background:var(--n-0);padding:0 22px;overflow:hidden;transition:border-color .25s ease,box-shadow .25s ease,transform .25s ease}
.faq-cards .faq-item::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--red-500) 0%,var(--red-400) 100%);opacity:0;transition:opacity .25s ease}
.faq-cards .faq-item:hover{border-color:rgba(215,25,32,0.4);transform:translateY(-2px);box-shadow:0 14px 30px -18px rgba(11,11,12,0.25)}
.faq-cards .faq-item.open{border-color:rgba(215,25,32,0.55);box-shadow:0 18px 38px -20px rgba(215,25,32,0.35)}
.faq-cards .faq-item.open::before{opacity:1}
.faq-cards .faq-q{padding:20px 0}
.faq-cards .faq-q::before{content:'0' counter(faq);font-family:var(--mono);font-size:0.68rem;font-weight:600;letter-spacing:0.1em;color:var(--red-600);flex:none}
.faq-cards .faq-a p{padding:0 0 20px 0}
@media(prefers-reduced-motion:reduce){.faq-cards .faq-item,.faq-cards .faq-item::before{transition:none}}
/* Thick red divider line above the "Before you ask" FAQ (services.html). */
.section-divider-red{height:6px;border-radius:3px;background:linear-gradient(90deg,var(--red-500) 0%,var(--red-400) 100%);box-shadow:0 6px 18px -6px rgba(215,25,32,0.55)}
/* Full intro column of the FAQ as one card. Shared by the "Before you ask"
   section on services.html and the "Quick answers" section on contact.html -
   both use .faq-intro-card. Dark premium finish matching the trust cards. */
.faq-intro-card{align-self:start;background:linear-gradient(180deg,#17171A 0%,#0B0B0C 100%);border:1px solid #26262B;border-radius:18px;padding:30px 28px;position:relative;overflow:hidden}
.faq-intro-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--red-500) 0%,var(--red-400) 100%)}
.faq-intro-card .label{color:#FF5147;margin-bottom:12px}
.faq-intro-card h2{color:var(--n-0);margin:0 0 10px}
.faq-intro-card p{color:#B9B9C0;margin:0}

/* ---- Badge / compliance row ---- */
.badge-row{display:flex;flex-wrap:wrap;gap:10px}
.badge{
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 16px;border-radius:999px;
  border:1px solid var(--line);background:var(--card);
  font-family:var(--mono);font-size:0.66rem;font-weight:500;letter-spacing:0.1em;
  text-transform:uppercase;color:var(--dim);
  box-shadow:var(--shadow-sm);
}
.badge svg{width:13px;height:13px;stroke:var(--accent-ink);fill:none;stroke-width:2}
.cta .badge{background:rgba(255,255,255,0.06);border-color:var(--on-line);color:var(--on-dim)}
.cta .badge svg{stroke:var(--accent)}


/* ---- Footer (dark, shared across all pages) ---- */
footer{
  position:relative;overflow:hidden;isolation:isolate;
  background:
    radial-gradient(55% 90% at 12% 0%,rgba(215,25,32,0.22),rgba(8,8,8,0) 60%),
    radial-gradient(40% 70% at 95% 100%,rgba(215,25,32,0.12),rgba(8,8,8,0) 60%),
    linear-gradient(180deg,#101013 0%,#080808 100%);
  border-top:1px solid var(--on-line);
  padding:68px 0 30px;color:var(--on-dim);
}
footer::before{
  content:'';position:absolute;top:0;left:0;right:0;height:3px;z-index:2;
  background:linear-gradient(90deg,var(--red-500) 0%,var(--red-400) 50%,var(--red-500) 100%);
  box-shadow:0 4px 20px -2px rgba(225,38,28,0.6);
}
.footer-top{
  position:relative;z-index:1;
  display:flex;align-items:center;justify-content:space-between;
  gap:20px 40px;flex-wrap:wrap;
  padding-bottom:30px;margin-bottom:24px;
  border-bottom:1px solid var(--on-line);
}
.footer-top .brand{color:var(--on-dark);font-size:1.45rem;font-weight:800;letter-spacing:-0.03em}
.footer-nav{display:flex;flex-wrap:wrap;gap:8px 10px}
.footer-nav a{font-size:0.86rem;font-weight:500;color:var(--on-dim);padding:8px 14px;border:1px solid transparent;border-radius:999px;transition:all .25s ease}
.footer-nav a:hover{color:#fff;border-color:rgba(225,38,28,0.5);background:rgba(225,38,28,0.12)}
.footer-bottom{
  position:relative;z-index:1;
  display:flex;justify-content:space-between;align-items:center;
  gap:14px 24px;flex-wrap:wrap;
  font-family:var(--mono);font-size:0.68rem;letter-spacing:0.06em;color:var(--on-faint);
}
.footer-meta{display:flex;align-items:center;gap:16px 22px;flex-wrap:wrap}
.footer-meta>a{color:var(--on-dim);transition:color .2s}
.footer-meta>a:hover{color:var(--red-300)}
/* social icons — base (light content sections, e.g. contact "follow us") */
.footer-social{display:flex;gap:8px}
.footer-social a{
  width:36px;height:36px;border-radius:10px;
  border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;
  color:var(--dim);transition:all .25s;
}
.footer-social a svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.footer-social a:hover{border-color:var(--accent-ink);color:var(--accent-ink);background:var(--accent-soft)}
/* footer is dark: override the icon chrome */
footer .footer-social a{width:40px;height:40px;border-radius:12px;border-color:rgba(255,255,255,0.14);color:var(--on-dim);background:rgba(255,255,255,0.03)}
footer .footer-social a:hover{
  border-color:transparent;background:linear-gradient(180deg,var(--red-500),var(--red-600));color:#fff;
  transform:translateY(-3px);box-shadow:0 12px 24px -8px rgba(215,25,32,0.6);
}
@media(max-width:640px){
  .footer-top{flex-direction:column;align-items:flex-start}
  .footer-bottom{flex-direction:column;align-items:flex-start}
}

/* ---- 404 page ---- */
body:has(.grid-bg){
  min-height:100vh;
  display:flex;align-items:center;justify-content:center;align-items:safe center;
  padding:28px;overflow-x:hidden;overflow-y:auto;
  background:var(--n-950);
  --bg:var(--n-950); --ink:var(--n-0); --dim:var(--n-400); --faint:var(--n-500);
  --accent-ink:var(--red-300);
  --line:rgba(255,255,255,0.16); --card:rgba(255,255,255,0.04);
}
.grid-bg{
  position:fixed;inset:0;
  background-image:
    linear-gradient(rgba(255,255,255,0.06) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,0.06) 1px,transparent 1px);
  background-size:60px 60px;
  z-index:0;pointer-events:none;
}
.wrap{position:relative;z-index:2;text-align:center;max-width:500px;margin:0 auto}
.code{font-weight:700;font-size:clamp(5rem,18vw,8rem);line-height:1;background:var(--grad-text);-webkit-background-clip:text;background-clip:text;color:transparent;letter-spacing:-0.05em}
.error-code{
  /* centred on the .code numerals (same clamp drives both) */
  position:absolute;top:calc(clamp(5rem,18vw,8rem)/2);left:50%;transform:translate(-50%,-50%);
  font-weight:300;font-size:clamp(12rem,40vw,22rem);
  color:rgba(255,255,255,0.04);line-height:1;
  pointer-events:none;user-select:none;
}
.msg{font-size:1.15rem;font-weight:600;margin:12px 0 8px;color:var(--ink)}
/* #6 404 .msg is now the page h1: pin the metrics the div had, so the
   global h1 rule (line-height 1.06, letter-spacing -0.03em) does not apply. */
.wrap h1.msg{font-size:1.15rem;font-weight:600;line-height:1.65;
  letter-spacing:normal;margin:12px 0 8px;color:var(--ink);font-family:'Inter',sans-serif}
.wrap p{color:var(--dim);font-size:0.95rem;line-height:1.7;margin:0 auto 32px;max-width:44ch}
.wrap .btn{display:inline-flex}
.dot{position:absolute;width:4px;height:4px;border-radius:50%;background:var(--accent);opacity:0.55}
.dot::after{content:'';position:absolute;inset:-4px;border-radius:50%;background:var(--accent);opacity:0.18;animation:pulse 2.5s ease-in-out infinite}
@keyframes pulse{0%,100%{transform:scale(1);opacity:0.18}50%{transform:scale(2);opacity:0}}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
.float-1{animation:float 6s ease-in-out infinite;position:absolute;top:15%;left:10%}
.float-2{animation:float 8s ease-in-out infinite 1s;position:absolute;top:20%;right:8%}
.float-3{animation:float 7s ease-in-out infinite 2s;position:absolute;bottom:25%;left:12%}
.float-4{animation:float 9s ease-in-out infinite 0.5s;position:absolute;bottom:18%;right:14%}

/* ---- Responsive ---- */
@media(max-width:768px){
  .hero{padding:116px 0 72px;min-height:auto}
  .section{padding:72px 0}
  .hero-actions{margin-bottom:36px}
  .container{padding:0 22px}
  #navbar{padding:0 20px;gap:10px}
  .panel{padding:28px 22px}
}

/* ============================================================
   Interaction layer — paired with main.js
   ============================================================ */

/* Reveal on scroll (only when JS is running, so no-JS still shows all) */
.js [data-reveal]{opacity:0;transform:translateY(22px);transition:opacity .7s cubic-bezier(.22,.61,.36,1),transform .7s cubic-bezier(.22,.61,.36,1)}
.js [data-reveal].is-visible{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.js [data-reveal]{opacity:1;transform:none;transition:none}}

/* Back to top */
.to-top{
  position:fixed;right:22px;bottom:22px;z-index:900;
  width:46px;height:46px;border-radius:14px;
  border:1px solid rgba(255,255,255,0.15);background:var(--n-950);color:#fff;
  box-shadow:var(--shadow);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;opacity:0;visibility:hidden;transform:translateY(10px);
  transition:all .25s ease;
}
.to-top.is-visible{opacity:1;visibility:visible;transform:none}
.to-top:hover{background:var(--brand);color:var(--on-dark);border-color:var(--brand)}
.to-top svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
@media(max-width:600px){.to-top{right:16px;bottom:16px;width:42px;height:42px}}

/* Form validation + status feedback */
.field.is-invalid input,.field.is-invalid select,.field.is-invalid textarea{border-color:var(--danger);box-shadow:0 0 0 3px rgba(215,25,32,0.15)}
.field-msg{font-size:0.76rem;color:var(--danger)}
.form-status{
  margin-top:14px;font-size:0.85rem;line-height:1.5;text-align:center;
  color:var(--accent-ink);
  opacity:0;transform:translateY(4px);transition:all .3s ease;
}
.form-status.is-shown{opacity:1;transform:none}

/* ============================================================
   Professionalism pass — layout & polish fixes
   ============================================================ */

/* Balanced headings kill orphan words ("...where they / matter.") */
h1,h2,h3,h4,.section-header p,.lede{text-wrap:balance}

/* Trim the dead space between a hero and the first section */
.hero + .section{padding-top:64px}

/* Careers: photo fills the column so it bottoms out with the form card */
.apply-left{display:flex;flex-direction:column}
/* The careers artwork is 1200x800, i.e. exactly 3:2. This override exists so
   the card matches that shape: .story-img's own aspect-ratio:4/3 would crop the
   sides, and flex:1 1 auto used to stretch the card to the height of the
   application form beside it, which made it taller than 3:2 and cropped about
   29% off the left and right at desktop widths. Sizing the card to 3:2 with the
   flex grow removed means object-fit:cover now has nothing to crop, and the
   whole illustration is visible with no letterbox bars either.
   Scoped to .apply-left, which only career.html uses, so about.html's .story-img
   and its 4/3 card are untouched. */
.apply-left .story-img{flex:0 0 auto;aspect-ratio:3/2;min-height:200px}

/* ============================================================
   Layout utilities (formerly inline style="" attributes)
   Each selector is written twice on purpose: .u-x.u-x gives
   specificity (0,2,0) so these beat the component rules they
   override (e.g. .trust-card.lead, .svc-card:hover) exactly as
   the old inline styles did, while staying in the cacheable
   stylesheet. Appended last, so they also win on source order.
   ============================================================ */
.u-accent-strong.u-accent-strong{font-weight:600;color:var(--accent-ink)}
/* Inline contextual links inside body copy. Doubled selector keeps the
   doubled-utility convention (specificity 0,2,0). Always underlined so a
   link is never mistaken for plain text (WCAG 1.4.1); the grey hairline
   stays visible on both light and dark sections. */
.u-ilink.u-ilink{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.2em;text-decoration-color:rgba(128,128,128,.75);transition:color .2s ease,text-decoration-color .2s ease}
.u-ilink.u-ilink:hover,.u-ilink.u-ilink:focus-visible{color:var(--accent-ink);text-decoration-color:currentColor}
.u-align-center.u-align-center{align-items:center}
.u-bg-alt.u-bg-alt{background:var(--bg2)}
.u-border-black.u-border-black{border-color:#0B0B0C}
.u-border-red.u-border-red{border-color:#E3131E}
.u-dot-1.u-dot-1{top:-40px;left:60px;width:6px;height:6px;background:var(--accent2)}
.u-dot-2.u-dot-2{width:6px;height:6px;background:var(--accent2)}
.u-dot-3.u-dot-3{bottom:-30px;left:40px}
.u-dot-4.u-dot-4{bottom:-40px;right:60px;width:6px;height:6px;background:var(--accent2)}
.u-honey.u-honey{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}
/* Thank-you card shown in place of the form after ?sent=1. */
.form-thanks{text-align:center;padding:48px 32px}
.form-thanks img{margin:0 auto 20px}
.form-thanks h2{font-size:1.6rem;margin:0 0 10px}
.form-thanks p{color:var(--dim);margin:0 auto;max-width:44ch}
.u-mb14.u-mb14{margin-bottom:14px}
.u-mb20.u-mb20{margin-bottom:20px}
.u-mb24.u-mb24{margin-bottom:24px}
.u-media-fluid.u-media-fluid{aspect-ratio:4/3;width:100%;height:auto}
.u-mt2.u-mt2{margin-top:2px}
.u-mt26.u-mt26{margin-top:26px}
.u-my14.u-my14{margin:14px 0 16px}
.u-my16.u-my16{margin:16px 0 16px}
.u-sub.u-sub{font-size:0.88rem;margin-bottom:22px}

/* ============================================================
   Digital Marketing landing page (digital-marketing.html)
   Everything below is page-scoped. The helper names in the inline
   SVG art (a-glass, a-line-f, a-dot, a-txt, a-float ...) are generic
   on purpose, so every one of them is nested under a dm- parent -
   none of these rules can reach another page.
   ============================================================ */

/* ---- Theme tokens ------------------------------------------
   These sections are NOT .section, so they never pick up the
   Type A/Type B variable block at the top of this file. Without
   the override below, h1..h3 would inherit --ink:#FFFFFF (root)
   and render white on white. ---- */
.dm-hero,.dm-band{
  position:relative;isolation:isolate;
  --ink:var(--n-950);--dim:var(--n-700);--faint:var(--n-600);
  --accent-ink:var(--red-600);   /* 5.6-6.0:1 on white AND on the #F7F7F7 band */
  --card:var(--n-0);--card-hover:var(--n-25);
  --line:var(--n-200);
  --shadow-sm:0 1px 2px rgba(20,4,4,0.10);
  --shadow:0 18px 40px -18px rgba(24,6,6,0.28);
  --shadow-lg:0 32px 72px -30px rgba(20,4,4,0.38);
}
.dm-hero,.dm-band-dark{
  --ink:var(--n-0);--dim:var(--n-400);--faint:var(--n-500);
  --accent-ink:var(--red-300);   /* 6.4:1 on charcoal */
  --card:rgba(255,255,255,0.05);--card-hover:rgba(255,255,255,0.08);
  --line:rgba(255,255,255,0.16);
  --shadow-sm:0 1px 2px rgba(0,0,0,0.45);
  --shadow:0 18px 40px -18px rgba(0,0,0,0.65);
  --shadow-lg:0 28px 64px -28px rgba(0,0,0,0.8);
}

/* ---- Hero palette, sampled from assets/digital-marketing/hero.webp ----
   The artwork is redder and hotter than the site tokens: its peak accent
   is a near-pure #FC0200 and its dominant base is a red-tinted #0B0001
   rather than a neutral #080808. Declared on .dm-hero only - the site
   tokens and the other five pages stay on #D71920. */
.dm-hero{
  --dm-red:#FC0200;         /* artwork peak accent */
  --dm-red-text:#FF3326;    /* same red lifted so small text clears AA */
  --dm-ink:#0B0001;         /* artwork's dominant base */
}

/* ---- 1. Hero ---- */
.dm-hero{
  overflow:hidden;
  /* horizontal padding keeps the glass canvas off the viewport edges
     at any width below its 1240px max */
  padding:80px 32px 76px;
  background:
    radial-gradient(58% 66% at 76% 42%,rgba(252,2,0,0.22),rgba(11,0,1,0) 72%),
    radial-gradient(70% 90% at 8% -12%,rgba(199,122,124,0.09),rgba(11,0,1,0) 60%),
    var(--dm-ink);
}
.dm-hero::before{
  content:'';position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(rgba(199,122,124,0.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(199,122,124,0.05) 1px,transparent 1px);
  background-size:64px 64px;
}
.dm-hero-orb{position:absolute;border-radius:50%;z-index:0;pointer-events:none}
.dm-hero-orb.o1{
  width:520px;height:520px;top:-170px;right:-120px;
  background:radial-gradient(circle at 34% 32%,rgba(199,122,124,0.36),rgba(252,2,0,0.14) 46%,rgba(252,2,0,0) 72%);
  animation:dmFloat 14s ease-in-out infinite;
}
.dm-hero-orb.o2{
  width:320px;height:320px;bottom:-150px;left:-110px;
  background:radial-gradient(circle at 40% 36%,rgba(199,122,124,0.16),rgba(199,122,124,0) 70%);
  animation:dmFloat 17s ease-in-out infinite reverse;
}
.dm-hero-orb.o3{
  width:130px;height:130px;top:62%;right:9%;
  background:radial-gradient(circle at 36% 30%,rgba(252,2,0,0.5),rgba(176,16,6,0.12) 68%);
  animation:dmPulse 7s ease-in-out infinite;
}
.dm-hero-canvas{
  position:relative;z-index:1;
  width:100%;max-width:1240px;margin:0 auto;
  padding:52px 0;
  border-radius:26px;
  /* Artwork layer: assets/digital-marketing/hero.webp. The gradient underneath
     stays as the fallback, so the hero still looks right if the file 404s.

     The FIRST layer is a readability scrim, listed first so it paints ON TOP
     of the artwork. Without it the hero copy fails AA at three of the four
     breakpoints, because the canvas box changes aspect ratio per breakpoint
     and `cover` therefore crops a different - and much brighter - part of the
     artwork behind the lede at narrower widths. Measured worst-case contrast
     for the 16.8px lede (#C8C8C8), sampling every pixel of its box:

       no scrim        1440 4.78:1   1024 2.91:1   768 4.40:1   390 4.10:1  (FAILS)
       this scrim      1440 7.71:1   1024 5.71:1   768 7.36:1   390 7.06:1  (AA+)

     Held flat at 0.40 through the text band and eased to 0.22 below it, so the
     artwork keeps some luminance at the base of the canvas instead of being
     flattened by a uniform veil. The lede keeps its #C8C8C8, so the h1/lede
     hierarchy is unchanged. This is a flat overlay - the SVG is not altered,
     cropped or regenerated. */
  background:
    linear-gradient(180deg,rgba(11,0,1,0.40) 0%,rgba(11,0,1,0.40) 72%,rgba(11,0,1,0.22) 100%),
    url('assets/digital-marketing/hero.webp') center center/cover no-repeat,
    linear-gradient(180deg,rgba(199,122,124,0.07),rgba(11,0,1,0.03));
  border:1px solid rgba(199,122,124,0.16);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  box-shadow:0 40px 90px -50px rgba(0,0,0,0.9);
}
/* The grid and copy sit above the artwork. */
.dm-hero-canvas > .container{position:relative;z-index:1}
.dm-hero-grid{display:grid;grid-template-columns:1.02fr 0.98fr;gap:48px;align-items:center}
.dm-hero-copy{min-width:0}
.dm-hero h1{
  color:#fff;font-weight:300;
  font-size:clamp(2.3rem,4.1vw,3.55rem);
  line-height:1.08;letter-spacing:-0.032em;
  margin-bottom:22px;
  text-wrap:balance;
}
/* "Build to grow." carries the emphasis; "grow." is the bright-red accent.
   The ramp is the artwork's own: rose -> hot red -> deep crimson. */
.dm-hero h1 em{font-style:normal;font-weight:600;color:#fff}
.dm-hero h1 em b{font-weight:800}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .dm-hero h1 em b{
    background:linear-gradient(112deg,#FF7A6E 0%,var(--dm-red) 50%,#B01006 100%);
    -webkit-background-clip:text;background-clip:text;
    color:transparent;-webkit-text-fill-color:transparent;
  }
}
/* Fallback for engines without background-clip:text: plain bright red. */
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .dm-hero h1 em b{color:var(--dm-red-text)}
}
.dm-hero .lede{font-size:1.05rem;line-height:1.75;max-width:52ch;color:var(--n-400);margin-bottom:26px}
.dm-hero .hero-actions{margin-bottom:0}

/* ---- Hero stage: orbital atmosphere ----
   Built entirely from CSS - no image assets, no 3D library.
   Three counter-rotating orbital shells, four glowing red spheres, two
   blurred organic blobs and three pulsing data points. Purely atmospheric:
   it carries the red/black depth behind the copy without competing with it.
   .dm-eco is aria-hidden in the markup, so the whole thing is decorative
   and never announced. Nothing here uses backdrop-filter, because a filter
   would flatten preserve-3d and kill the depth. */
.dm-eco{
  position:relative;
  /* Height is driven by min-height, not aspect-ratio: the orbit shells need
     ~500px of vertical room to read as ellipses rather than collapse. */
  min-height:500px;
  --eco-red:#FC0200;
}
.dm-eco-scene{
  position:absolute;inset:0;
  perspective:1400px;
  perspective-origin:50% 46%;
  transform-style:preserve-3d;
  pointer-events:none;
}

/* --- orbital shells: thin, faint, elliptical, slowly counter-rotating --- */
.dm-eco-ring{
  position:absolute;top:50%;left:50%;
  border:1px solid rgba(255,255,255,.10);
  border-radius:50%;
  transform-style:preserve-3d;
}
.dm-eco-ring.r1{
  width:112%;height:64%;margin:-32% 0 0 -56%;
  transform:rotateX(72deg) rotateZ(0deg);
  border-color:rgba(199,122,124,.15);
  animation:dmSpinA 58s linear infinite;
}
.dm-eco-ring.r2{
  width:88%;height:52%;margin:-26% 0 0 -44%;
  transform:rotateX(72deg) rotateY(28deg);
  border-style:dashed;border-color:rgba(252,2,0,.26);
  animation:dmSpinB 44s linear infinite reverse;
}
.dm-eco-ring.r3{
  width:132%;height:78%;margin:-39% 0 0 -66%;
  transform:rotateX(78deg) rotateY(-22deg);
  border-color:rgba(127,66,69,.10);
  animation:dmSpinA 72s linear infinite reverse;
}

/* --- soft organic blobs (the glowing spheres were removed) --- */
.dm-blob{
  position:absolute;border-radius:50%;
  filter:blur(38px);
  transform:translateZ(-140px);
}
.dm-blob.b1{
  width:260px;height:200px;top:8%;left:26%;
  background:radial-gradient(circle,rgba(176,16,6,.34),rgba(176,16,6,0) 70%);
  animation:dmFloat 19s ease-in-out infinite reverse;
}
.dm-blob.b2{
  width:220px;height:170px;bottom:4%;right:14%;
  background:radial-gradient(circle,rgba(199,122,124,.13),rgba(199,122,124,0) 70%);
  animation:dmFloat 23s ease-in-out infinite;
}

/* tiny red data points riding the orbits */
.dm-eco-node{
  position:absolute;width:7px;height:7px;border-radius:50%;
  background:radial-gradient(circle,#F0C4C1,var(--eco-red) 70%,rgba(252,2,0,0) 80%);
  box-shadow:0 0 10px 2px rgba(252,2,0,.5);
}
.dm-eco-node.n1{top:9%;left:41%;animation:dmPulse 4.5s ease-in-out infinite}
.dm-eco-node.n2{bottom:12%;left:24%;animation:dmPulse 6s ease-in-out infinite .8s}
.dm-eco-node.n3{top:62%;right:4%;animation:dmPulse 5.2s ease-in-out infinite 1.4s}


/* ---- Motion (all of it dies under prefers-reduced-motion) ----
   dmFloat / dmPulse animate the standalone `translate` and `scale` properties
   rather than `transform`, so the ecosystem layers can hold a static 3D pose
   (translateZ + rotateY) and still bob. The two compose: transform applies
   after translate. Engines without `translate`/`scale` support simply render
   the rest pose, which is the correct resting state. */
@keyframes dmFloat{0%,100%{translate:0 0}50%{translate:0 -13px}}
@keyframes dmPulse{0%,100%{scale:1;opacity:1}50%{scale:1.14;opacity:.7}}
/* Orbit rings already carry their own rotateX/rotateY, so these spin on Z
   and re-state the tilt - overwriting the transform would flatten the ring. */
@keyframes dmSpinA{from{transform:rotateX(72deg) rotateY(0) rotateZ(0)}to{transform:rotateX(72deg) rotateY(0) rotateZ(360deg)}}
@keyframes dmSpinB{from{transform:rotateX(72deg) rotateY(28deg) rotateZ(0)}to{transform:rotateX(72deg) rotateY(28deg) rotateZ(-360deg)}}

/* ---- Section bands ----
   Same shared 28 KB artwork as every other white section on the
   site; the dm cards are opaque, so it reads in the gutters. */
.dm-band{
  padding:96px 0;
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-0);
}
.dm-band-alt{
  background:url('assets/bento/background_1440x838.webp') center center/cover no-repeat,var(--n-50);
}
/* Hairline between two adjacent service bands (#services then #web-design).
   A dark band is not an option here: the bento cards are #111111 and would
   sink into it, so the separation is a tint change plus a 1px rule. */
.dm-band-split{border-top:1px solid var(--line);border-bottom:1px solid var(--line)}

/* Artwork layer for the light content bands (#web-design, #process).
   Source: assets/digital-marketing/hero-background.webp
   (authored to 1600 x 900). Replaces the shared bento webp for these bands;
   the flat #F7F7F7 tint stays underneath as the fallback so the sections still
   read correctly before the file is uploaded or if it 404s.

   The band copy is forced to white by the token block below - see the
   CONTRAST note there. */
.dm-band-art{
  /* Fallback colour must be near-black, NOT #F7F7F7: the copy here is white,
     so a light fallback would leave the copy invisible if the SVG 404s or is
     still uploading. Matches the artwork's own darkest tone. */
  background:
    url('assets/digital-marketing/hero-background.webp') center center/cover no-repeat,
    #140303;
  /* Re-declare the dark-band tokens so every descendant follows, rather than
     patching h2/p one at a time (that left .step h3 + .step p in #process as
     dark-on-dark). h1..h3 use color:var(--ink) and .label uses var(--accent-ink),
     so this one block retints the whole section. Declared after .dm-band
     (equal specificity) so source order wins. --card stays white: the .dm-why
     tiles in #why are light cards and read well against the dark artwork. */
  --ink:var(--n-0);--dim:var(--n-300);--faint:var(--n-400);
  --accent:var(--red-200);--accent-ink:var(--red-200);  /* 7.2:1 on the darkest
                                                        patch of the artwork */
  --line:rgba(255,255,255,0.24);
  --card:var(--n-0);
}

/* Scrim between the artwork and the white copy. Dark, not light - the copy on
   these bands is white. Measured on the #web-design heading/lede against the
   real cover crop, worst case being the BRIGHTEST patch behind the text:
     no scrim  -> heading 1.76:1, lede 2.01:1   (both fail)
     0.30      -> heading 3.48:1, lede 3.94:1   (heading only)
     0.45      -> heading 5.21:1, lede 5.81:1   (both clear AA)
   Now APPLIED to both artwork bands. It is a flat translucent overlay - it
   does not touch, crop or regenerate the image, and the red still reads
   through it, which is what lifts these bands from "fails" to "premium".
   Weighted darker at the top and bottom so the header copy and the card
   grid both sit on the deepest part of the wash. */
.dm-band-art-scrim{
  position:relative;
}
.dm-band-art-scrim::before{
  content:'';position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(9,0,1,0.34) 0%,rgba(9,0,1,0.54) 46%,rgba(9,0,1,0.46) 100%),
    radial-gradient(130% 100% at 16% 8%,rgba(9,0,1,0.30),rgba(9,0,1,0) 60%);
}
.dm-band-art-scrim > .container{position:relative;z-index:1}
.dm-band-dark{
  background:var(--n-950);
}
.dm-band-dark::after{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(rgba(255,255,255,0.03) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,0.03) 1px,transparent 1px);
  background-size:64px 64px;
}
.dm-display{font-size:clamp(1.85rem,3.4vw,2.85rem);line-height:1.14}

/* ---- 4. Strategy ---- */
/* Compacted at the client's request. The 7-node list was the tall column at
   520px and drove the section to 712px on desktop, so that is where the
   reduction goes: node padding 13->10, gap 12->8, number badge 36->32, label
   0.98->0.92rem. Copy margins and the 56px column gap come down a little too.
   Nothing goes below 4.5:1 - the node label is still #0D0D0D on #FFFFFF. */
/* Section artwork: the same technology-hero-bg.webp used by
   #why, at the same 55% white scrim, so the two sections render the image
   identically. Deliberately NOT .dm-band-art - that hardcodes the red/black
   artwork and flips the copy to white, which on this white artwork is
   white-on-white. This section is on the light theme, so copy keeps dark
   tokens. (It was a .dm-band-dark near-black section until this artwork was
   requested; the dark tokens, white copy and #141414 cards are all reverted.)

   Same red-streak problem as #why, but worse here: sampling the decoded
   pixels under the actual text ink, #strategy's copy column sits over artwork
   as dark as L=0.011, where #why's sat at L=0.44. That is why the red text
   below is --red-700 and not the --red-600 the light theme hands to .label. */
#strategy{
  background:
    linear-gradient(rgba(255,255,255,0.55),rgba(255,255,255,0.55)),
    url('assets/digital-marketing/technology-hero-bg.webp') center center/cover no-repeat,
    var(--n-0);
}
.dm-strategy{display:grid;grid-template-columns:1.05fr 0.95fr;gap:44px;align-items:center}
/* .label inherits --accent-ink, which the light theme sets to --red-600.
   On the artwork that is 3.85:1, under the 4.5 the 11.2px label needs, so it
   is pinned to --red-700 here: 4.95:1. Same reason as the heading em below. */
.dm-strategy-copy .label{display:block;margin-bottom:12px;color:var(--red-700)}
.dm-strategy-copy h2{margin-bottom:14px}
/* The emphasised line sits directly on the artwork, so --red-700 rather than
   a light-theme red: 4.51:1 against the darkest streak behind it, where
   --red-600 manages only 3.51:1. The heading is clamp-sized display type, so
   WCAG asks 3:1. */
.dm-strategy-copy h2 em{font-style:normal;color:var(--red-700)}
/* Body copy sits on a brand-red plate. The text had just been set to black,
   but black cannot stay: #0D0D0D on #D71920 is 3.80:1 and this is 16px
   regular, where WCAG asks 4.5:1. White is 5.11:1, so the plate inverts the
   text rather than dimming it. Keeping black instead would need --red-300
   (#FF4B44) at 5.87:1, which is a pale pink - it reads as a highlight, not
   as the brand red.

   Plate is block-level, not inline-block: on an inline element vertical
   padding paints without touching the line box, and on inline-block it
   adds to line height and shoves the rest of the page down. This is a
   multi-line block, so the padding simply makes the block taller. */
.dm-strategy-copy p{
  margin-bottom:20px;max-width:52ch;
  background:var(--red-500);color:var(--n-0);
  padding:18px 22px;border-radius:var(--r);
}
.dm-flow-v{list-style:none;position:relative}
.dm-flow-v::before{
  content:'';position:absolute;left:30px;top:22px;bottom:22px;width:2px;
  background:linear-gradient(180deg,var(--red-500) 0%,rgba(215,25,32,0.16) 100%);
}
/* Nodes are opaque WHITE cards, matching the .dm-why cards on this page.
   Opaque matters for the spine: .dm-flow-v::before sits at left:30px, which
   runs straight through the badge, so a see-through card would let the red
   line show under the label. Opaque keeps the spine visible only in the 8px
   gaps between nodes, which is what makes it read as a connector.

   Border is the brand red rather than var(--line): the card is white and the
   band behind it is now a white artwork, so a pale grey hairline would leave
   the card edge undefined. #D71920 on #FFFFFF is 5.11:1, well past the 3:1
   WCAG asks of a meaningful boundary. */
.dm-node{
  position:relative;z-index:1;
  display:flex;align-items:center;gap:14px;
  background:var(--n-0);border:1px solid var(--red-500);
  border-radius:var(--r);padding:10px 16px;
  margin-bottom:8px;
}
.dm-node:last-child{margin-bottom:0}
/* Near-black disc with a white numeral - 19.44:1, and the original treatment
   from before this section was briefly a dark band. */
.dm-node-n{
  flex:none;width:32px;height:32px;display:grid;place-items:center;
  border-radius:50%;background:var(--n-950);color:var(--n-0);
  font-family:var(--mono);font-size:0.68rem;font-weight:600;letter-spacing:0.04em;
}
.dm-node-l{font-size:0.92rem;font-weight:600;letter-spacing:-0.01em;color:var(--n-950)}
/* 07 Growth keeps the red badge to mark the end of the chain. */
.dm-node.is-final .dm-node-n{background:var(--red-500);color:var(--n-0)}
@media(max-width:960px){
  .dm-strategy{grid-template-columns:1fr;gap:30px}
}

/* ---- 5. How we work: 6-up flow ---- */
/* Back to the plain 6-up card: 14px radius, no tilt, no folded corner, no red
   header strip. The only things kept from the two rejected treatments are the
   colour fixes below, which were approved.
   Note the border resolves through var(--line), which .dm-band-art sets to
   rgba(255,255,255,0.22) - so on this section the 3px top edge is a 22%-white
   hairline on a white card, i.e. all but invisible. That is the pre-existing
   behaviour, unchanged by the reverts.
   Compacted at the client's request, same as #strategy: padding 26/28 -> 18/20
   and 20px -> 16px horizontally, STEP label margin 12 -> 8. The horizontal cut
   also widens the text column, which is what removes a wrapped line on the
   4-line cards. Contrast is unchanged - still #0D0D0D on #FFFFFF. */
.dm-flow{grid-template-columns:repeat(6,1fr);gap:18px}
.dm-flow .step{
  padding:18px 16px 20px;
  background:var(--n-0);
  border:1px solid var(--line);
  border-top:3px solid var(--accent);   /* was var(--line), which on a
     .dm-band-art section resolves to rgba(255,255,255,0.22) - a white
     hairline on a white card, i.e. invisible. The brand red gives the
     top edge a visible, consistent accent. */
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);
  /* No hover or click reaction, by request. transition:none rather than just
     deleting the old transition - the shared `.step` rule further up carries
     `transition:border-color .3s`, so removing ours would let that fall back in
     and the border would still animate. */
  transition:none;
}
.dm-flow .step::before{display:none}
/* The six process cards are static statements, not links or buttons, so nothing
   here is clickable and the cursor stays default. On top of dropping the old
   lift-and-shadow hover, this re-asserts the resting values against the two
   shared hover rules that also match these elements:
     .step:hover{border-top-color:var(--accent)}
     .step:hover::before{background/box-shadow} on the connector dot
   Both were already inert here - the border-top is already var(--accent) and
   ::before is display:none - so this is belt-and-braces: it means a later edit
   to the shared .step rules cannot silently reintroduce motion on this page.

   Scoped to .dm-flow, which only ever wraps the #process list. The identical
   hover effects on the steps in index.html and contact.html are untouched. */
.dm-flow .step:hover{
  border-color:var(--line);
  border-top-color:var(--accent);
  transform:none;
  box-shadow:var(--shadow-sm);
}
.dm-flow .step:hover::before{display:none}
/* STEP 01-06 labels. These inherited --accent-ink, which a .dm-band-art
   section sets to #FF6A5E - only 2.81:1 on the white card. The brand red is
   4.67:1 and matches the h3 below it. */
.dm-flow .step .step-n{color:var(--red-400);margin-bottom:8px}
/* One-off: pull this section's header closer to the grid. The global
   .section-header margin-bottom is 52px, which is generous next to a single
   row of cards. Scoped by id because it is specific to this section, not a
   reusable band behaviour like .dm-band-tight. */
#process .section-header{margin-bottom:34px}
@media(max-width:1100px){.dm-flow{grid-template-columns:repeat(3,1fr)}}
@media(max-width:760px){.dm-flow{grid-template-columns:repeat(2,1fr);gap:18px}}
@media(max-width:440px){.dm-flow{grid-template-columns:1fr}}
/* Black body copy on all six steps. The .dm-flow .step card is opaque #FFFFFF,
   so dark ink is safe here regardless of the artwork behind the section:
   measured 19.4:1 against the card. Without this the paragraphs inherit
   --dim, which a .dm-band-art section sets to #D9D3D3 - 1.5:1 on white. */
.dm-flow .step p{color:var(--n-950)}
/* Step headings in brand red. These were inheriting --ink (#FFFFFF on a
   .dm-band-art section) and landing white-on-white inside the opaque card,
   1.00:1. #E1261C is the light-theme accent already used by .step-n and
   .dm-why-n, so the steps stay consistent with the rest of the page. */
.dm-flow .step h3{color:var(--red-400)}

/* ---- 6. Why ByteSynthify ---- */
/* Compacted at the client's request, consistent with #strategy and #process.
   The 3-line .dm-display heading is most of the header block, so the savings
   come from the band padding (via .dm-band-tight), the head margin, the label
   margin, the tile padding and the numeral margin. Colours are unchanged. */
/* Section artwork: technology-hero-bg.webp (1400x784).
   Deliberately NOT .dm-band-art - that class hardcodes the red/black artwork
   AND flips the copy to white, which on this white artwork is white-on-white.
   This section stays on the light theme, so the copy keeps its dark tokens.

   The white overlay is a scrim, not decoration, and 55% is the measured
   minimum - 50% puts the 11px .label at 4.47:1, just under the 4.5 it needs.
   Sampling the decoded pixels under the ACTUAL text ink (not the empty rest
   of each 721px box) gives, at 55%: label 4.63:1, red heading lines 4.63 and
   3.53:1, near-black "Data always." 11.25:1. The artwork's median luminance
   is 239/255, so the light majority of the image is barely touched; the veil
   is there to tame dark-red streaks that reach rgb(78,0,0).

   Note the two red heading lines sit either side of the text's own luminance
   - the darkest pixel behind line 1 is L=0.44 (lighter than the red) and
   behind line 2 it is L=0.018 (darker). Lifting the background therefore
   helps line 1 and hurts line 2, and no single scrim value fixes both. That
   is why the heading red below is --red-600 rather than --red-400.

   Stacked as a gradient in the background rather than a ::before scrim like
   .dm-band-art-scrim: a flat fill has no z-index to get wrong, and the cards
   below are opaque so they sit on the artwork unaffected. */
#why{
  background:
    linear-gradient(rgba(255,255,255,0.55),rgba(255,255,255,0.55)),
    url('assets/digital-marketing/technology-hero-bg.webp') center center/cover no-repeat,
    var(--n-0);
}
.dm-why-head{max-width:760px;margin-bottom:30px}
.dm-why-head .label{display:block;margin-bottom:12px}
/* "Strategy first. / Creative second." in brand red. --red-600, NOT the
   --red-400 used by the .dm-why h3 headings: those sit on opaque white cards,
   this sits on the section artwork, and #E1261C drops to 2.70:1 behind the
   second line's dark-red streak. #C4121A clears both lines at 4.63 and
   3.53:1. The heading is clamp(1.85rem,3.4vw,2.85rem) bold, i.e. 29.6-45.6px,
   so WCAG asks 3:1 for large text.

   The span exists because CSS cannot select "the text before a <br>" - the
   two lines had to be wrapped to be coloured independently of the <em>. The
   trailing <em>Data always.</em> is deliberately left near-black and italic,
   so it stays the typographic payoff rather than a third red line. */
.dm-why-head .dm-why-lead{color:var(--red-600)}
.dm-why-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
/* Card. position:relative + overflow:hidden are load-bearing: the ghost
   numeral is an absolutely-positioned child pinned past the top-right corner,
   and the card has to clip it so it cannot bleed into the gutter or the
   neighbouring card. The extra top padding reserves the space the numeral
   occupies, so the headings still start on one line across all four cards. */
.dm-why{
  position:relative;overflow:hidden;
  background:var(--n-0);border:1px solid var(--red-500);
  border-radius:var(--r-lg);padding:74px 20px 24px;
}
/* Deliberately NO :hover rule on this card, and no transition either.
   These four are static statements, not links or buttons, so they do not
   move, lift or change colour on pointer-down - nothing here is clickable.
   #D71920 on the band's #FFFFFF is 4.84:1, comfortably past the 3:1 that
   WCAG asks of a meaningful boundary, so the red frame reads without help. */
/* Ghost numeral: outlined, not filled, pinned into the top-right corner.
   Decorative only - the markup sets aria-hidden, so it is read as the
   ornament it is rather than announced as a list number. -webkit-text-stroke
   is used for the outline; -webkit-text-fill-color:transparent then hollows
   the glyph. The solid color underneath is the fallback for any engine that
   does not support text-stroke, where it renders as a plain tinted numeral
   rather than disappearing. */
.dm-why-n{
  position:absolute;top:-14px;right:-6px;
  display:block;font-family:var(--mono);font-weight:600;
  font-size:5.4rem;line-height:1;letter-spacing:-0.04em;
  color:rgba(215,25,32,0.10);
  -webkit-text-stroke:1.5px rgba(215,25,32,0.34);
  -webkit-text-fill-color:transparent;
  pointer-events:none;user-select:none;
}
/* Card headings in brand red. #E1261C is the light-theme accent: 4.67:1 on
   the card's #FFFFFF. The ghost numeral above is decorative, so this heading
   is the element carrying the real information contrast. */
.dm-why h3{color:var(--red-400);margin-bottom:9px}
.dm-why p{font-size:0.9rem;line-height:1.65}
/* The ghost numeral is sized in px, not em: it is an ornament locked to the
   card, and tying it to the type scale made it overflow once the grid
   collapsed. These two steps scale it back as the cards get narrower, and
   reclaim the top padding it needed at 4-up. */
@media(max-width:900px){
  .dm-why-grid{grid-template-columns:1fr 1fr}
  .dm-why{padding-top:66px}
  .dm-why-n{font-size:4.4rem;top:-12px;right:-4px}
}
@media(max-width:560px){
  .dm-why-grid{grid-template-columns:1fr}
  .dm-why{padding-top:58px}
  .dm-why-n{font-size:3.6rem;top:-9px;right:-2px}
}

/* ---- 7. Contact ---- */
/* Red radial washes over the solid #0D0D0D. Declared with .dm-band-dark so it
   outranks the plain .dm-band-dark background at equal specificity. */
.dm-band-dark.dm-glow{
  background:
    radial-gradient(1100px 620px at 8% 4%,rgba(215,25,32,0.26),transparent 62%),
    radial-gradient(820px 520px at 92% 96%,rgba(215,25,32,0.18),transparent 60%),
    var(--n-950);
}
.dm-contact{display:grid;grid-template-columns:0.95fr 1.05fr;gap:52px;align-items:start}
.dm-contact-copy .label{display:block;margin-bottom:16px}
.dm-contact-copy h2{margin-bottom:16px}
.dm-contact-copy p{margin-bottom:30px;max-width:46ch}

/* Contact tiles - same bento language as the service sections. */
.dm-tiles{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:0}
.dm-tile{
  display:flex;flex-direction:column;gap:7px;min-width:0;
  background:rgba(255,255,255,0.04);
  border:1px solid rgba(255,255,255,0.14);
  border-radius:var(--r-lg);
  padding:17px 18px 18px;
  transition:background .25s ease,border-color .25s ease,transform .25s ease;
}
a.dm-tile:hover{
  background:rgba(255,255,255,0.08);
  border-color:rgba(255,106,94,0.55);
  transform:translateY(-2px);
}
.dm-tile-n{
  font-family:var(--mono);font-size:0.6rem;font-weight:600;
  letter-spacing:0.16em;text-transform:uppercase;color:var(--red-200);
}
.dm-tile-v{
  font-size:0.95rem;font-weight:600;letter-spacing:-0.01em;line-height:1.35;
  color:var(--n-0);overflow-wrap:anywhere;
}
/* .dm-tile-wide and .dm-offers were removed with the contact section's
   "What we take on" chip tile. The four remaining tiles are all single-track,
   so the grid is a plain 2x2 with no full-width child. */

.dm-contact .contact-form{
  border-color:rgba(255,255,255,0.14);
  box-shadow:0 40px 80px -44px rgba(0,0,0,0.95);
}
.dm-contact .form-submit{width:100%}
.dm-contact .contact-form .form-status{color:var(--red-200)}
@media(max-width:960px){.dm-contact{grid-template-columns:1fr;gap:42px}}
@media(max-width:520px){.dm-tiles{grid-template-columns:1fr}}

/* ---- Footer: labelled 4-column directory (digital-marketing.html ONLY) ----
   The base `footer` / `.footer-top` / `.footer-nav` / `.footer-bottom` rules
   near the top of this file are shared by index, about, services, career and
   contact. Everything below is scoped to .footer-dm so those five pages keep
   their existing footer. If this design is adopted site-wide, promote these
   into the shared block and drop the class. */
.footer-dm{padding:64px 0 26px}
.dm-foot{
  position:relative;z-index:1;
  display:grid;grid-template-columns:1.6fr 1fr 1.15fr;
  gap:34px 40px;
  padding-bottom:34px;
  border-bottom:1px solid var(--on-line);
}
/* Brand lockup (digital-marketing.html only).
   The lockup REPLACES both the old inline 28x28 SVG and the "ByteSynthify /
   Studio." text, rather than sitting beside them.

   brand-mark.png is CROPPED to the artwork's own bounding box. The supplied
   source had the logo occupying only 52.5% of the canvas height, with ~57px of
   empty padding above and below, and a true ratio of 4.29:1 rather than the
   2.5:1 the canvas claimed. Displayed uncropped, a 44px-tall element showed a
   logo of only 23px - which is why it read as "not noticeable". Cropped, the
   full height is now logo.

   50px tall in the header and 60px in the footer. This was 58px, chosen to fill
   the 64px bar, but that left the logo at 90.6% of the header height with ~3px
   of clearance above and below - the mark crowded the bar. At 50px it sits at
   78% and clears by ~7px, so the header reads as a bar with a logo in it rather
   than a logo with a bar around it. The 64px bar is unchanged, so the header
   does not shift.

   200x50 holds the source's exact 4:1 ratio, so there is no distortion. Both
   sizes are far below the 576px source width, so this is always downscaled and
   never blurred. width/height are also set as HTML attributes on the <img> so
   the box is reserved before the file loads and the page does not shift - keep
   the header <img> attributes in step with this rule. */
.brand-mark{display:block;width:200px;height:50px;flex:none}
.dm-foot-brand .brand{margin-bottom:16px}
.dm-foot-brand .brand-mark{width:240px;height:60px}
.dm-foot-tag{
  font-size:0.92rem;line-height:1.6;color:var(--on-dim);
  max-width:34ch;margin-bottom:20px;
}
/* .dm-foot-cta was removed with the footer's "Start a project" button; the
   Contact column still carries a plain "Start a project" link. */
/* Column headings. These are real h2s so the footer is navigable by heading in
   a screen reader, which means the global h1,h2,h3 rule has to be overridden
   - it would otherwise give them display sizing and var(--ink). */
.dm-foot-h{
  font-family:var(--mono);font-size:0.64rem;font-weight:600;
  line-height:1.3;letter-spacing:0.18em;text-transform:uppercase;
  color:var(--on-faint);margin:0 0 14px;
}
.dm-foot-col ul{list-style:none;display:flex;flex-direction:column;gap:9px}
.dm-foot-col a{font-size:0.9rem;color:var(--on-dim);transition:color .2s}
.dm-foot-col a:hover{color:#fff}
.dm-foot-bar{
  position:relative;z-index:1;
  display:flex;align-items:center;justify-content:space-between;
  gap:14px 24px;flex-wrap:wrap;
  padding-top:22px;
  font-family:var(--mono);font-size:0.68rem;letter-spacing:0.06em;color:var(--on-faint);
}
/* Below 900px the tracks collapse. The brand keeps its own full-width row
   (it is a tall block - wordmark, tagline, CTA - and squeezing it beside a
   list wastes the space), and the two remaining lists sit side by side beneath
   it, so the footer is 2 rows rather than 3. */
@media(max-width:900px){
  .dm-foot{grid-template-columns:repeat(2,1fr);gap:28px 32px}
  .dm-foot-brand{grid-column:1/-1}
}
/* At 390 two columns leave ~150px each, too narrow for the email address, so
   the Contact list drops to its own full-width row. */
@media(max-width:560px){
  .dm-foot{grid-template-columns:1fr 1fr;gap:26px 24px;padding-bottom:28px}
  .dm-foot-col:last-child{grid-column:1/-1}
  .dm-foot-tag{font-size:0.86rem;line-height:1.55;margin-bottom:16px}
  .dm-foot-col a{font-size:0.86rem}
  .dm-foot-bar{padding-top:18px;gap:12px 18px}
}

/* ---- Responsive: hero + ecosystem ---- */
@media(max-width:1040px){
  .dm-hero-grid{grid-template-columns:1fr;gap:56px}
  /* single column: cap the stage so it does not stretch to the full
     container width and leave the orbit cards marooned at the edges.
     `width:100%` is required - auto inline margins stop a grid item
     stretching, which would collapse the stage to its 0-width content. */
  .dm-eco{width:100%;max-width:640px;margin-inline:auto}
}
@media(max-width:980px){
  /* Below this width the ecosystem can no longer breathe: the browser frame and
     the orbiting cards would collide and the smallest ones would be unreadable.
     It is decorative, so it is dropped entirely and the copy carries the hero. */
  .dm-eco{display:none}
}
@media(max-width:768px){
  .dm-hero{padding:64px 22px 60px}
  .dm-hero-canvas{padding:36px 0;border-radius:20px}
  .dm-band,.dm-band-dark{padding:72px 0}
  .dm-hero .lede{font-size:1rem}
}
/* Opt-in reduction of the band padding, for sections whose content is already
   tall (a 7-item list, a long card grid). MUST stay below every .dm-band
   padding rule above - the max-width:768px block re-declares .dm-band at 72px,
   and at equal specificity source order decides, so putting this earlier
   silently loses at mobile widths. */
.dm-band-tight{padding:76px 0}
@media(max-width:768px){.dm-band-tight{padding:60px 0}}
@media(max-width:560px){
  .dm-node{padding:12px 14px}
  .dm-flow-v::before{left:31px}
}
@media(max-width:440px){
  .dm-hero-canvas{padding:26px 0}
}
