/* 
   Order inside this file: tokens, reset, layout, labels, buttons, navigation, touch glow,
   page hero, effects, cards, footer, motion, breakpoints, reduced motion. */

/* Design tokens */
:root {
  color-scheme: dark;

  /* Colour */
  --bg: #0A0C0B;
  --black: #090B0A;
  --surface: #101312;
  --line: #1E2421;
  --text: #FFFFFF;
  --muted: #A9B3AE;
  --placeholder: #8A938F;
  --accent: #39FF14;
  --accent-rgb: 57, 255, 20;
  --danger: #FF6B6B;

  /* Type: IBM Plex Serif for headings, Inter for everything readable */
  --font-heading: 'IBM Plex Serif', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-ui: var(--font-body);   /* buttons and menus, only differs for Hebrew */

  --size-xs: .75rem;
  --size-sm: .875rem;
  --size-base: 1rem;
  --size-lg: 1.125rem;

  /* Spacing */
  --sp-xs: .5rem;
  --sp-sm: 1rem;
  --sp-md: 1.5rem;
  --sp-lg: 2rem;
  --sp-xl: 3rem;
  --sp-2xl: 5rem;
  --sp-3xl: 8rem;

  /* Shape and motion */
  --r-sm: 4px;
  --r-md: 6px;
  --r-lg: 8px;
  --r-full: 9999px;
  --ease: cubic-bezier(.2, .7, .2, 1);
  --fade-ease: cubic-bezier(.45, 0, .3, 1);
  --fade-time: 2s;
  --t-fast: .15s ease-out;
  --t-med: .3s ease-out;
  --nav-h: 72px;

  /* Leading. Unitless multipliers, so line height always follows the element's own font size. */
  --lh-head: 1.15;    /* major headings */
  --lh-sub: 1.3;      /* subheadings */
  --lh-small: 1.4;    /* small text, captions and labels */
  --lh-body: 1.5;     /* body text */
  --lh-long: 1.6;     /* long reading text, the top of the comfortable range */

  /* --hero-h is the full screen cover (home, and every cover on phones). --hero-top is how far down the heading starts,
     the same on every page, so the heading never jumps when moving between pages. */
  --hero-h: calc(100vh - var(--nav-h));
  --hero-top: clamp(3rem, 22vh, 10rem);
  --band-h: clamp(380px, 56vh, 540px);   /* height of the photograph band on inner pages. Dark space fills the rest of the first screen. */

  /* Direction of the side fades on heroes. Right to left pages flip it to 270deg. */
  --side-fade: 90deg;
}

@supports (height: 100svh) { :root { --hero-h: calc(100svh - var(--nav-h)); } }   /* svh ignores the phone address bar */

/* Reset and base */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-size: 100%;   /* 16px by default, and it follows the visitor's text size setting */
  scrollbar-width: thin;   /* a slim scrollbar in the site colour instead of the wide grey one */
  scrollbar-color: rgba(var(--accent-rgb), .35) var(--black);
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  padding-top: var(--nav-h);
  font-family: var(--font-body);
  font-size: var(--size-base);
  line-height: var(--lh-body);
  font-optical-sizing: auto;
  background: var(--bg);
  color: var(--text);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 500;
  letter-spacing: -.012em;
  color: var(--text);
  text-wrap: balance;
  overflow-wrap: normal;
  hyphens: manual;
}

/* Global heading scale in rem. Components set their own sizes with a class. */
h1 { font-size: 2.5rem; line-height: var(--lh-head); }
h2 { font-size: 2rem; line-height: var(--lh-head); }
h3 { font-size: 1.5rem; line-height: var(--lh-head); }
h4 { font-size: 1.25rem; line-height: var(--lh-sub); }
h5 { font-size: 1.125rem; line-height: var(--lh-sub); }
h6 { font-size: 1rem; line-height: var(--lh-sub); }

p { color: var(--muted); text-wrap: pretty; overflow-wrap: break-word; }
strong { color: var(--text); font-weight: 500; }
img, video, svg { display: block; max-width: 100%; height: auto; }
ul, ol { list-style: none; }
a { color: inherit; text-decoration: none; transition: color var(--t-fast); }
button { cursor: pointer; border: 0; background: none; font: inherit; color: inherit; -webkit-tap-highlight-color: transparent; }
input, textarea, select { font: inherit; border: 0; outline: 0; background: none; color: inherit; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
::selection { background: rgba(var(--accent-rgb), .25); color: var(--text); }

.text-link { color: var(--accent); border-bottom: 1px solid rgba(var(--accent-rgb), .4); }

/* Text for screen readers only */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Layout and utilities */
.container { width: 90%; max-width: 1200px; margin: 0 auto; }

.section { padding: clamp(4.5rem, 9vw, 8rem) 0; }
.section-sm { padding: clamp(3rem, 6vw, 5rem) 0; }
.section-sm.pt-0 { padding-top: 0; }
.section-divider { border: 0; border-top: 1px solid var(--line); margin: 0; }

.section-intro { max-width: 760px; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-intro h2 { font-size: clamp(2rem, 4.2vw, 3.2rem); }
.section-intro p { margin-top: var(--sp-sm); max-width: 60ch; font-size: var(--size-lg); }

.mt-sm { margin-top: var(--sp-sm); }
.mt-lg { margin-top: var(--sp-lg); }
.hidden { display: none !important; }
.heb { direction: rtl; unicode-bidi: isolate; }

/* The honeypot field in the contact form. It is hidden from people, so only bots fill it in. */
.hp-field {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; inset-inline-start: -9999px; top: 8px; z-index: 2000;
  padding: .7rem 1rem; border-radius: var(--r-sm);
  background: var(--accent); color: #04120A; font-weight: 600;
}
.skip-link:focus { inset-inline-start: 12px; }

/* Small uppercase labels. Page files only add what differs, such as spacing. */
.kicker, .page-eyebrow, .eyebrow, .tier-label, .project-kicker, .case-kicker, .contact-detail-item .label {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  line-height: var(--lh-small);
  text-transform: uppercase;
  color: var(--accent);
}
.kicker, .page-eyebrow, .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .85em;
  margin-bottom: 1.25rem;
}
.kicker::before, .page-eyebrow::before { content: ''; width: 1.6em; height: 1px; background: currentColor; }

/* Other small text */
small, .form-note, .case-note, .legal-date, .showcase-caption-text, .footer-bottom { line-height: var(--lh-small); }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  min-height: 48px; padding: .9em 1.6em;   /* em, so the padding follows the button's own text size */
  font: 600 .9375rem/1.25 var(--font-body);
  letter-spacing: -.005em;
  border: 1px solid transparent; border-radius: var(--r-sm);
  transition: background-color .2s, color .2s, border-color .2s, box-shadow .2s;
  -webkit-tap-highlight-color: transparent;   /* no blue flash over the link box when tapped. Links need this, buttons already have it */
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #04120A; }
.btn-primary:hover { background: #7DFF63; border-color: #7DFF63; }
.btn-outline { color: var(--text); border-color: rgba(255, 255, 255, .22); }
.btn-outline:hover { color: var(--accent); border-color: var(--accent); background: rgba(var(--accent-rgb), .06); }
.btn[disabled] { opacity: .6; cursor: progress; }

/* A small icon inside a normal button, for example the YouTube button. The size follows the button's text.
   It is grey at rest and shows its true colours on hover, like the YouTube link in the footer. */
.btn-icon { flex: none; width: 1.4em; height: 1.4em; object-fit: contain; filter: grayscale(1) brightness(.85); transition: filter var(--t-fast); }
.btn:is(:hover, :focus-visible) .btn-icon { filter: none; }

/* Round icon buttons for WhatsApp and YouTube, three times the size of a normal button.
   The size is in rem, so it grows with the visitor's text size. On hover a neon line draws around the ring.
   The line is the after layer and a faint soft halo sits under it as the before layer.
   The tip of the line fades over 6 degrees so it reads as light. */
@property --ring-sweep { syntax: '<angle>'; inherits: false; initial-value: 6deg; }

.btn.btn-outline:is(.btn-whatsapp, .btn-youtube) {
  --ring-track: #262a28;
  --ring-size: 9rem;         /* 144px at the default text size, three times the old 48px */
  --ring-icon: 7.125rem;     /* three times the old 38px */
  position: relative;
  width: var(--ring-size); height: var(--ring-size);
  min-width: var(--ring-size); min-height: var(--ring-size);
  padding: 0;
  overflow: visible;
  background: transparent;
  border-color: transparent;
  border-radius: 50%;
  box-shadow: inset 0 0 0 3px var(--ring-track);
  -webkit-touch-callout: none; user-select: none; -webkit-user-select: none;   /* no selection box or press and hold menu over the icon */
}
.btn:is(.btn-whatsapp, .btn-youtube):focus-visible { outline: 0; }

.btn:is(.btn-whatsapp, .btn-youtube) img {
  width: var(--ring-icon); height: var(--ring-icon); object-fit: contain;
  pointer-events: none; -webkit-user-drag: none; user-select: none; -webkit-user-select: none;   /* the link takes the tap, so the picture itself can never be selected or dragged */
  filter: grayscale(1) brightness(.85);
  transition: filter .35s ease, transform .35s ease;
}
.btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active) img {
  transform: scale(1.06);
  filter: brightness(1.1)
    drop-shadow(0 0 2px rgba(var(--accent-rgb), .9))
    drop-shadow(0 0 16px rgba(var(--accent-rgb), .45));
}

.btn:is(.btn-whatsapp, .btn-youtube)::before,
.btn:is(.btn-whatsapp, .btn-youtube)::after {
  --ring-sweep: 6deg;
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  pointer-events: none;
  transform: scaleX(-1);
  background: conic-gradient(from 0deg,
    var(--accent) calc(var(--ring-sweep) - 6deg),
    transparent var(--ring-sweep));
  opacity: 0;
  /* On mouse out the line draws back first and only then fades */
  transition: --ring-sweep .8s var(--ease), opacity .2s ease .6s;
}
.btn:is(.btn-whatsapp, .btn-youtube)::after {
  mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 4px), #000 calc(100% - 2px), transparent 100%);
}
.btn:is(.btn-whatsapp, .btn-youtube)::before {
  inset: -4px;
  filter: blur(2px);
  mask: radial-gradient(farthest-side, transparent calc(100% - 16px), #000 calc(100% - 6px), transparent 100%);
}
.btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active)::before,
.btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active)::after {
  --ring-sweep: 366deg;   /* 6 degrees past a full circle, so the fade lands off the end and the ring closes solid */
  transition: --ring-sweep .8s var(--ease), opacity .2s ease 0s;
}
.btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active)::after { opacity: 1; }
.btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active)::before { opacity: .35; }

/* Navigation */
.site-nav {
  position: fixed; inset: 0 0 auto; z-index: 1000;
  height: var(--nav-h);
  display: flex; align-items: center;
  background: rgba(9, 11, 10, .82);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);   /* Safari 17 and older still need the prefix */
  backdrop-filter: blur(16px) saturate(1.2);
  border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.site-nav .container { display: flex; align-items: center; justify-content: space-between; }

.nav-logo { display: flex; align-items: center; gap: .7rem; min-width: 0; min-height: 48px; }
.nav-logo img { height: 34px; width: auto; }
.nav-logo-text { font: 500 1.3rem/1.2 var(--font-heading); letter-spacing: -.01em; }
.logo-tech { color: var(--text); }
.logo-jcorp { color: var(--accent); }

.nav-links { display: flex; align-items: center; gap: var(--sp-lg); }
.nav-links a:not(.btn) { position: relative; padding: .4rem 0; font-size: .9375rem; color: var(--muted); }
.nav-links a:not(.btn)::after {
  content: ''; position: absolute; inset-inline-start: 0; bottom: 0; width: 0; height: 1px;
  background: var(--accent); transition: width var(--t-med);
}
.nav-links a:not(.btn):hover, .nav-links a:not(.btn).active { color: var(--text); }
.nav-links a:not(.btn):hover::after, .nav-links a:not(.btn).active::after { width: 100%; }
.nav-links .btn { padding: .75em 1.3em; font-size: .875rem; color: var(--accent); border-color: rgba(var(--accent-rgb), .5); }
.nav-links .btn:hover, .nav-links .btn.active { background: var(--accent); border-color: var(--accent); color: #04120A; }
.nav-links a.lang-switch { font-size: .875rem; font-weight: 500; }

.nav-hamburger { display: none; flex-direction: column; justify-content: center; align-items: center; gap: 5px; width: 48px; height: 48px; }
.nav-hamburger span { display: block; width: 22px; height: 2px; border-radius: 2px; background: var(--text); transition: transform var(--t-med), opacity var(--t-fast); }
.nav-hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-hamburger.open span:nth-child(2) { opacity: 0; }
.nav-hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Language menu in the top bar. Pages with only two languages still use it. */
.lang-menu-item { position: relative; }
.lang-menu { position: relative; }
.lang-menu summary {
  display: inline-flex; align-items: center; gap: .6em;
  padding: .4em .75em; border: 1px solid rgba(255, 255, 255, .18); border-radius: var(--r-sm);
  font-size: .875rem; font-weight: 500; color: inherit; list-style: none; cursor: pointer;
}
.lang-menu summary::-webkit-details-marker { display: none; }
.lang-menu summary img { width: 1.4em; height: 1.4em; }
.lang-menu summary::after {
  content: ''; display: inline-block; margin-inline-start: .5em; width: .45em; height: .45em;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.lang-menu[open] summary { border-color: var(--accent); }
.lang-menu ul {
  position: absolute; top: calc(100% + .4rem); inset-inline-end: 0; z-index: 60; min-width: 9rem; padding: .3rem;
  background: #0d100f; border: 1px solid rgba(255, 255, 255, .14); border-radius: var(--r-md);
}
.lang-menu li a { display: block; padding: .5rem .7rem; border-radius: var(--r-sm); white-space: nowrap; }
.lang-menu li a:hover, .lang-menu li a:focus-visible { background: rgba(255, 255, 255, .07); }

/* Full screen mobile menu. It sits under the fixed bar, which keeps the logo and the close button.
   It fades and blurs in, and the page behind it cannot scroll while it is open. */
.mobile-menu {
  position: fixed; inset: 0; z-index: 999;
  display: flex; flex-direction: column;
  padding: calc(var(--nav-h) + var(--sp-md)) 7% max(var(--sp-lg), env(safe-area-inset-bottom));
  background: rgba(9, 11, 10, .94);
  -webkit-backdrop-filter: blur(22px) saturate(1.2); backdrop-filter: blur(22px) saturate(1.2);
  overflow-y: auto; overscroll-behavior: contain;
  visibility: hidden; opacity: 0; pointer-events: none;
  transition: visibility 0s linear .4s, opacity .4s ease;
}
.mobile-menu.open { visibility: visible; opacity: 1; pointer-events: all; transition-delay: 0s; }
body.menu-open { overflow: hidden; }
.mobile-menu > a {
  display: flex; align-items: center; min-height: 56px; padding: 0 .25rem;
  font: 500 clamp(1.35rem, 5.4vw, 1.75rem)/1.2 var(--font-heading); color: var(--muted);
  border-bottom: 1px solid var(--line);
  opacity: 0; transform: translateY(10px);
  transition: opacity .45s ease, transform .45s ease, color var(--t-fast);
}
.mobile-menu.open > a { opacity: 1; transform: none; }
.mobile-menu.open > a:nth-of-type(2) { transition-delay: .05s; }
.mobile-menu.open > a:nth-of-type(3) { transition-delay: .1s; }
.mobile-menu.open > a:nth-of-type(4) { transition-delay: .15s; }
.mobile-menu > a.active, .mobile-menu > a:hover, .mobile-menu > a:active { color: var(--text); }
.mobile-menu > a.active { color: var(--accent); }
.mobile-menu > a:last-of-type {   /* the Start a project link */
  margin-top: var(--sp-md); justify-content: center; border: 1px solid rgba(var(--accent-rgb), .5);
  border-radius: var(--r-md); color: var(--accent); font: 600 1rem/1.25 var(--font-body);
}
.mobile-langs { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: auto; padding-top: var(--sp-md); justify-content: center; }
.mobile-langs a, .mobile-langs .lang-current {
  display: inline-flex; align-items: center; justify-content: center; min-width: 48px; min-height: 48px; padding: 0 1rem;
  font-size: .9375rem; font-weight: 500; color: var(--muted); border: 1px solid var(--line); border-radius: var(--r-md);
}
.mobile-langs .lang-current { color: var(--accent); border-color: rgba(var(--accent-rgb), .55); }

/* Touch glow. scripts/touch.js adds one element and moves it under the finger.
   It is a wide, feathered glow with no visible edge that flickers very slightly, like static charge.
   It never receives clicks, so it cannot get in the way of the page. */
.touch-charge {
  position: fixed; top: 0; left: 0; z-index: 2000;
  width: 320px; height: 200px; margin: -100px 0 0 -160px;
  pointer-events: none; opacity: 0;
  background:
    radial-gradient(ellipse at center, rgba(var(--accent-rgb), .22) 0%, rgba(var(--accent-rgb), .10) 36%, rgba(var(--accent-rgb), .035) 60%, transparent 78%);
  mix-blend-mode: screen;
  transition: opacity .6s ease;
  will-change: transform, opacity;
}
.touch-charge.is-on { opacity: 1; transition-duration: .15s; animation: charge-flicker 2.8s linear infinite; }

@keyframes charge-flicker {
  0%, 100% { filter: brightness(1); }
  22% { filter: brightness(.82); }
  41% { filter: brightness(1.1); }
  63% { filter: brightness(.9); }
  84% { filter: brightness(1.05); }
}

/* Page hero, used on every inner page. Each page file sets its own background photograph.
   The heading position comes from --hero-top in the tokens, so every page matches the home cover. */
.page-hero {
  position: relative; isolation: isolate; display: flex; align-items: flex-start;
  min-height: var(--band-h);   /* a band that fades into the page. On phones it is full screen, see the 768px block */
  margin-bottom: max(0px, calc(var(--hero-h) - var(--band-h)));   /* dark space under the band, so the first screen shows only the cover and the next section starts below it */
  padding: var(--hero-top) 0 var(--sp-xl);
  background-size: cover; background-position: center right; overflow: hidden;
}
.page-hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(var(--side-fade), rgba(9, 11, 10, .94) 0%, rgba(9, 11, 10, .7) 55%, rgba(9, 11, 10, .35) 100%),
    linear-gradient(0deg, var(--bg) 0%, transparent 38%);
}
.page-hero-content { position: relative; max-width: 780px; }
.page-hero h1 { font-size: clamp(2.4rem, 5.2vw, 4.25rem); }
.page-hero h1 span { color: var(--accent); }
.page-hero .sub { max-width: 56ch; margin-top: var(--sp-md); font-size: var(--size-lg); }

/* Faint engineering grid on every hero, fading out toward the far side.
   The home hero in pages.css uses it too. */
.hero::after, .page-hero::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: linear-gradient(var(--side-fade), #000 0%, transparent 65%);
}

  .holo::before, .holo::after { transition: none; }
  
@media (hover: hover) {
  .holo:hover {
    border-color: rgba(var(--accent-rgb), .5);
    box-shadow: 0 16px 36px rgba(0, 0, 0, .45), 0 0 20px rgba(var(--accent-rgb), .12);
    transform: scale(1.012);
  }
}
.holo:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .4);
}

/* Image bands. Full width photo strips that dissolve into the page: a soft top and bottom fade,
   a side vignette, a restrained colour grade and, where supported, a slow scroll drift.
   Each page file sets the photograph. */
.image-band {
  position: relative; isolation: isolate; overflow: hidden;
  height: clamp(240px, 38vw, 500px);
  mask-image: linear-gradient(180deg, transparent 0%, #000 26%, #000 74%, transparent 100%);
}
.image-band::before {   /* the photograph */
  content: ''; position: absolute; inset: -8% 0; z-index: -2;
  background-size: cover; background-repeat: no-repeat; background-position: center;
  filter: saturate(.75) contrast(1.05) brightness(.82);
  transform: scale(1.06);
}
.image-band::after {   /* vignette, side blend and a trace of brand tint */
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(120% 95% at 50% 50%, transparent 40%, rgba(10, 12, 11, .78) 100%),
    linear-gradient(90deg, var(--bg) 0%, transparent 24%, transparent 76%, var(--bg) 100%),
    linear-gradient(rgba(var(--accent-rgb), .035), rgba(var(--accent-rgb), .035));
}
/* Parallax band. A picture sits behind a whole section, under a dark wash so the text stays easy to read,
   and drifts slowly as the page scrolls. Each page file sets the photograph with a modifier class.
   The drift is shared with the image bands. */
.parallax { position: relative; isolation: isolate; overflow: hidden; }
.parallax::before {   /* the photograph */
  content: ''; position: absolute; inset: -12% 0; z-index: -3;
  background-size: cover; background-repeat: no-repeat; background-position: center;
  filter: saturate(.75) contrast(1.05) brightness(.6);
  transform: scale(1.08);
}
.parallax::after {   /* dark wash, fading into the page at the top and bottom */
  content: ''; position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background:
    linear-gradient(180deg, var(--bg) 0%, rgba(10, 12, 11, .62) 24%, rgba(10, 12, 11, .62) 76%, var(--bg) 100%),
    linear-gradient(rgba(var(--accent-rgb), .035), rgba(var(--accent-rgb), .035));
}

@keyframes band-drift {
  from { transform: translateY(-4%) scale(1.08); }
  to   { transform: translateY(4%) scale(1.08); }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .image-band::before, .parallax::before { animation: band-drift linear both; animation-timeline: view(); }
  }
}

/* Card surface shared by the call to action strip, packages, project cards and the contact form */
.cta-strip, .tier, .project-card, .contact-form-wrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

/* Call to action strip */
.cta-strip {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-xl);
  padding: clamp(2rem, 5vw, 4rem);
}
.cta-strip h2 { font-size: clamp(1.5rem, 3vw, 2.4rem); }
.cta-strip p { max-width: 36rem; }
.cta-actions { display: flex; flex-wrap: wrap; gap: var(--sp-sm); }

/* Feature call to action, used on the home, services and portfolio pages: a short pitch on the left,
   Subscribe on YouTube and Contact us on the right, over a soft green glow. */
.cta-strip--feature {
  position: relative; isolation: isolate; overflow: hidden;
  border-color: rgba(var(--accent-rgb), .25);
  background:
    radial-gradient(60% 120% at 0% 0%, rgba(var(--accent-rgb), .10), transparent 65%),
    var(--surface);
}
.cta-strip--feature::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 3px; z-index: 1;
  background: linear-gradient(180deg, var(--accent), transparent);
}
.cta-strip--feature .cta-copy { max-width: 36rem; }
.cta-strip--feature .eyebrow { margin-bottom: var(--sp-sm); }
.cta-strip--feature p:not(.eyebrow) { margin-top: var(--sp-sm); font-size: var(--size-lg); }
.cta-strip--feature .cta-actions { flex-shrink: 0; align-items: center; }

/* Footer */
.site-footer { padding: var(--sp-2xl) 0 var(--sp-lg); background: var(--black); border-top: 1px solid var(--line); }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: var(--sp-xl); margin-bottom: var(--sp-xl); }
.footer-logo { margin-bottom: var(--sp-sm); font: 500 1.6rem/1.2 var(--font-heading); letter-spacing: -.01em; }
.footer-brand p { max-width: 320px; font-size: var(--size-sm); }
.footer-col h4 { margin-bottom: var(--sp-md); font: 600 .8125rem/1.3 var(--font-heading); letter-spacing: .12em; text-transform: uppercase; color: var(--text); }
.footer-col ul { display: flex; flex-direction: column; gap: var(--sp-xs); }
.footer-col a { font-size: var(--size-sm); color: var(--muted); }
.footer-col a:hover { color: var(--accent); }
.footer-youtube { display: inline-flex; align-items: center; gap: .5em; }
.footer-youtube img { width: 1.4em; height: 1.4em; filter: grayscale(1) brightness(.85); transition: filter var(--t-fast); }
.footer-youtube:hover img { filter: none; }
.footer-bottom { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-sm); padding-top: var(--sp-md); border-top: 1px solid var(--line); font-size: var(--size-xs); color: var(--muted); }

/* Motion. The scroll reveal uses an animation rather than a transition, so it never fights
   the hover transitions on cards. */
.fade-in { opacity: 0; }
.fade-in.visible { opacity: 1; animation: reveal .65s var(--ease) backwards; }
.delay-100 { animation-delay: .1s !important; }
.delay-150 { animation-delay: .15s !important; }
.delay-200 { animation-delay: .2s !important; }
@keyframes reveal { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* One orchestrated entrance on load */
.hero-content > *, .page-hero-content > * { animation: rise .7s var(--ease) backwards; }
.hero-content > :nth-child(2), .page-hero-content > :nth-child(2) { animation-delay: .08s; }
.hero-content > :nth-child(3), .page-hero-content > :nth-child(3) { animation-delay: .16s; }
.hero-content > :nth-child(4), .page-hero-content > :nth-child(4) { animation-delay: .24s; }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

@media (scripting: none) { .fade-in { opacity: 1; } }

/* Cover reveal. Each cover (home hero, page heroes, image bands) holds a black veil element.
   When main.js reports that the photograph has loaded and decoded, it adds the ready state to the cover
   and the veil fades to transparent over the fade time. The veil is plain opacity, so it behaves
   the same in every browser. If the script never runs, the veil lifts by itself after 4 seconds.
   Visitors with reduced motion or without scripting never see a veil.
   Each fade has two keyframe names on purpose. Switching to a new animation name restarts it,
   which is how the ready state takes over from the late fallback. */
.cover-veil { display: none; }

@keyframes veil-reveal { from { opacity: 1; } to { opacity: 0; } }
@keyframes veil-late   { from { opacity: 1; } to { opacity: 0; } }

@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  .cover-veil {
    display: block; position: absolute; inset: 0; z-index: -1;
    background: #000; pointer-events: none;
    animation: veil-late var(--fade-time) var(--fade-ease) 4s forwards;
  }
  .is-ready > .cover-veil { animation: veil-reveal var(--fade-time) var(--fade-ease) forwards; }
}

/* Breakpoints for the shared parts, from large to small */
@media (max-width: 1024px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
  .cta-strip { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 900px) {
  .nav-links { display: none; }
  .nav-hamburger { display: flex; }
}

@media (max-width: 768px) {
  .page-hero { min-height: var(--hero-h); margin-bottom: 0; }   /* phones: the cover itself fills the first screen */
  .page-hero::before { background: linear-gradient(180deg, rgba(9, 11, 10, .82), rgba(9, 11, 10, .72)); }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; text-align: center; }
  .image-band { height: clamp(200px, 52vw, 320px); }
}

@media (max-width: 640px) {
  .cta-strip--feature .cta-actions { width: 100%; flex-direction: column; align-items: stretch; }
}

@media (max-width: 480px) {
  :root { --sp-2xl: 3.5rem; --sp-3xl: 5rem; }
  .btn { width: 100%; }
  .nav-links .btn { width: auto; }
  .cta-strip { padding: var(--sp-xl) var(--sp-md); }
  .nav-logo img { height: 30px; }
  .nav-logo-text { font-size: 1.15rem; }
}

@media (max-width: 360px) {
  .container { width: 92%; }
  .nav-logo-text { font-size: 1.05rem; }
}

/* Touch targets. On narrow screens and on touch devices, footer links and top bar links are at least 48px tall. */
@media (max-width: 768px), (hover: none) and (pointer: coarse) {
  .footer-col ul { gap: 0; }
  .footer-col li a { display: flex; align-items: center; min-height: 48px; }
}
@media (hover: none) and (pointer: coarse) {
  .nav-links a:not(.btn) { display: inline-flex; align-items: center; min-height: 48px; }
}

/* Reduced motion. Page files add their own rules for their own elements. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .fade-in.visible, .hero-content > *, .page-hero-content > * { animation: none; }
  .touch-charge.is-on { animation: none; }
  .image-band::before, .parallax::before { animation: none; }
  .holo::before, .holo::after { transition: none; }
  .btn:is(.btn-whatsapp, .btn-youtube) img,
  .btn:is(.btn-whatsapp, .btn-youtube)::before,
  .btn:is(.btn-whatsapp, .btn-youtube)::after,
  .btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active)::before,
  .btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active)::after { transition: none; }
  .btn:is(.btn-whatsapp, .btn-youtube):is(:hover, :focus-visible, :active) img { transform: none; }
}
