/* ==========================================================================
   CHILLEX TECHNICAL SERVICES LLC
   Custom stylesheet — everything Tailwind utilities don't cover cleanly.
   Loaded on every page after the Tailwind CDN.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. BASE
   -------------------------------------------------------------------------- */

:root {
  --cyan:       #00A8CC;
  --cyan-hover: #008CAE;
  --cyan-light: #58D5FB;
  --navy:       #0F172A;
  --steel:      #1E293B;
  --alert:      #E11D48;
  --surface:    #F8FAFC;
  --line:       #E2E8F0;
  --ink:        #334155;
  --header-h:   5rem;
}

* { -webkit-tap-highlight-color: transparent; }

html {
  scroll-behavior: smooth;
  /* offset anchor jumps so headings don't hide under the sticky header */
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  margin: 0;
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ink);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Stitch hid scrollbars entirely. Restoring them — removing the scroll
   affordance is a usability regression, especially on long service pages. */
::-webkit-scrollbar        { width: 10px; height: 10px; }
::-webkit-scrollbar-track  { background: #EEF2F5; }
::-webkit-scrollbar-thumb  { background: #C3CDD4; border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: #9FADB7; }

img { max-width: 100%; height: auto; display: block; }

/* --------------------------------------------------------------------------
   2. BRAND UTILITIES  — CSS fallback for the Tailwind theme
   --------------------------------------------------------------------------
   These duplicate the custom tokens defined in assets/js/tailwind-config.js.

   Why duplicate them?  The Tailwind Play CDN is a third-party runtime
   dependency. If it is blocked, slow, or its config fails to register, every
   custom class silently produces nothing — which turns `bg-navy` + `text-white`
   sections into white text on a white background. Unreadable.

   Defining them here as plain CSS means the site is always legible, with or
   without the CDN. Values are identical, so there is no visual conflict.
   Delete this block only if you compile Tailwind properly (see README).
   -------------------------------------------------------------------------- */

/* Backgrounds */
.bg-navy          { background-color: #0F172A; }
.bg-steel         { background-color: #1E293B; }
.bg-alert         { background-color: #E11D48; }
.bg-cyan          { background-color: #00A8CC; }
.bg-cyan-hover    { background-color: #008CAE; }
.bg-cyan-light    { background-color: #58D5FB; }
.bg-cyan-deep     { background-color: #00677E; }
.bg-line          { background-color: #E2E8F0; }
.bg-surface       { background-color: #F8FAFC; }
.bg-surface-alt   { background-color: #EFF4F7; }
.bg-surface-card  { background-color: #FFFFFF; }
.bg-surface-sunken{ background-color: #EAEFF1; }

/* Text */
.text-navy        { color: #0F172A; }
.text-steel       { color: #1E293B; }
.text-alert       { color: #E11D48; }
.text-cyan        { color: #00A8CC; }
.text-cyan-hover  { color: #008CAE; }
.text-cyan-light  { color: #58D5FB; }
.text-cyan-pale   { color: #B5EBFF; }
.text-cyan-deep   { color: #00677E; }
.text-ink         { color: #334155; }
.text-ink-muted   { color: #64748B; }
.text-line        { color: #E2E8F0; }   /* decorative separators between list items */

/* Borders */
.border-line      { border-color: #E2E8F0; }
.border-cyan      { border-color: #00A8CC; }
.border-navy      { border-color: #0F172A; }
.border-alert     { border-color: #E11D48; }
.border-t-cyan    { border-top-color: #00A8CC; }
.border-l-cyan    { border-left-color: #00A8CC; }
.border-l-alert   { border-left-color: #E11D48; }
.border-b-cyan    { border-bottom-color: #00A8CC; }

/* Typography */
.font-display     { font-family: "Plus Jakarta Sans", system-ui, sans-serif; }
.font-body        { font-family: Inter, system-ui, sans-serif; }

.text-display-xl  { font-size: clamp(2.25rem, 5vw, 3rem);     line-height: 1.15; letter-spacing: -0.02em; font-weight: 800; }
.text-display-lg  { font-size: clamp(1.875rem, 4vw, 2.25rem); line-height: 1.2;  letter-spacing: -0.01em; font-weight: 700; }
.text-display-md  { font-size: clamp(1.25rem, 2.5vw, 1.5rem); line-height: 1.3;                           font-weight: 600; }
.text-body-lg     { font-size: 1.125rem;  line-height: 1.7; }
.text-body-base   { font-size: 1rem;      line-height: 1.65; }
.text-label       { font-size: 0.875rem;  line-height: 1.4;  font-weight: 500; }
.text-micro       { font-size: 0.75rem;   line-height: 1.4;  font-weight: 500; }

/* Layout */
.max-w-container  { max-width: 1280px; }
.gap-gutter       { gap: 1.5rem; }
.rounded-md       { border-radius: 0.75rem; }

.py-section       { padding-top: 4rem;  padding-bottom: 4rem; }
.pt-section       { padding-top: 4rem; }
.pb-section       { padding-bottom: 4rem; }
.py-section-lg    { padding-top: 6rem;  padding-bottom: 6rem; }
.pb-section-lg    { padding-bottom: 6rem; }

@media (min-width: 1024px) {
  .lg\:py-section     { padding-top: 4rem;  padding-bottom: 4rem; }
  .lg\:py-section-lg  { padding-top: 6rem;  padding-bottom: 6rem; }
  .lg\:pb-section-lg  { padding-bottom: 6rem; }
}

/* Shadows */
.shadow-card  { box-shadow: 0 1px 3px rgba(15,23,42,0.06), 0 1px 2px rgba(15,23,42,0.04); }
.shadow-lift  { box-shadow: 0 12px 32px rgba(15,23,42,0.12); }
.shadow-panel { box-shadow: 0 8px 30px rgba(15,23,42,0.08); }
.shadow-nav   { box-shadow: 0 1px 8px rgba(15,23,42,0.05); }

/* Gradient colour stops — Tailwind's gradient utilities read these variables */
.from-navy  { --tw-gradient-from: #0F172A; --tw-gradient-to: rgba(15,23,42,0);  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
.from-cyan  { --tw-gradient-from: #00A8CC; --tw-gradient-to: rgba(0,168,204,0); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
.to-navy    { --tw-gradient-to: #0F172A; }
.to-steel   { --tw-gradient-to: #1E293B; }
.to-cyan-deep { --tw-gradient-to: #00677E; }

/* Safety net: any element that opts into white text must never sit on an
   unpainted background. If a dark utility fails to resolve, this guarantees
   the section still has a dark backdrop rather than white-on-white. */
section.text-white:not([class*="bg-"]) { background-color: #0F172A; }

/* --------------------------------------------------------------------------
   3. ACCESSIBILITY
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--navy);
  color: #fff;
  font-weight: 600;
  border-radius: 0 0 0.5rem 0;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
  border-radius: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   3. SCROLL REVEAL
   -------------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(1.75rem);
  transition: opacity 0.7s ease-out, transform 0.7s ease-out;
  will-change: opacity, transform;
}
.reveal.is-revealed { opacity: 1; transform: none; }

.reveal-delay-1 { transition-delay: 0.10s; }
.reveal-delay-2 { transition-delay: 0.20s; }
.reveal-delay-3 { transition-delay: 0.30s; }

/* --------------------------------------------------------------------------
   4. COMPONENTS
   -------------------------------------------------------------------------- */

/* Eyebrow label — "— OUR EXPERTISE" */
.eyebrow {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: 0.875rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--cyan);
}
.eyebrow::before {
  content: ""; width: 2rem; height: 2px;
  background: currentColor; flex: none;
}
.eyebrow--center::after {
  content: ""; width: 2rem; height: 2px;
  background: currentColor; flex: none;
}

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.875rem 2rem;
  border-radius: 0.5rem;
  font-size: 0.9375rem; font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;
  line-height: 1.2;
}
.btn-primary { background: var(--cyan); color: #fff; box-shadow: 0 4px 14px rgba(0,168,204,0.25); }
.btn-primary:hover { background: var(--cyan-hover); transform: translateY(-2px); box-shadow: 0 8px 22px rgba(0,168,204,0.32); }

.btn-outline { background: transparent; color: var(--cyan); border-color: var(--cyan); }
.btn-outline:hover { background: rgba(0,168,204,0.08); transform: translateY(-2px); }

.btn-on-dark { background: transparent; color: var(--cyan-light); border-color: var(--cyan-light); }
.btn-on-dark:hover { background: rgba(88,213,251,0.12); transform: translateY(-2px); }

.btn-alert { background: var(--alert); color: #fff; box-shadow: 0 4px 14px rgba(225,29,72,0.3); }
.btn-alert:hover { background: #be123c; transform: translateY(-2px); }

.btn-whatsapp { background: #25D366; color: #fff; }
.btn-whatsapp:hover { background: #1da851; transform: translateY(-2px); }

/* Cards */
.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}
.card-hover:hover {
  transform: translateY(-0.5rem);
  box-shadow: 0 12px 32px rgba(15,23,42,0.12);
  border-color: rgba(0,168,204,0.4);
}

/* Cyan top rule that grows on hover */
.card-topline { position: relative; overflow: hidden; }
.card-topline::before {
  content: ""; position: absolute; top: 0; left: 0;
  height: 4px; width: 0; background: var(--cyan);
  transition: width 0.4s ease; z-index: 2;
}
.card-topline:hover::before { width: 100%; }

/* Media panel — an image that fills its grid cell without driving the row height.
   ---------------------------------------------------------------------------
   In a side-by-side card, `h-full` on an <img> resolves to `height: 100%`, which
   cannot compute against a grid cell of indeterminate height. Browsers fall back
   to the image's intrinsic aspect ratio — so a portrait photo (e.g. 740×1600)
   renders over 1000px tall and drags the whole card with it.

   Absolutely positioning the image removes it from the height calculation
   entirely: the row is sized by the text column, and the photo crops to fit.  */
.media-panel {
  position: relative;
  overflow: hidden;
  min-height: 15rem;          /* floor for the stacked mobile layout */
  background: #EAEFF1;        /* shows while the image decodes */
}
.media-panel > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* On dark sections the default light placeholder flashes before the image
   decodes. This keeps the gap dark instead. */
.media-panel--dark { background: #1E293B; }

/* Crop anchor. `cover` centres by default, which is right most of the time —
   but when the subject sits high in a tall portrait photo, centring cuts the
   head off. These anchor the crop to a different edge. */
.media-panel--top    > img { object-position: top; }
.media-panel--bottom > img { object-position: bottom; }
@media (min-width: 1024px) {
  .media-panel { min-height: 22rem; }
}

/* Offset shadow block behind feature images */
.img-offset { position: relative; }
.img-offset::after {
  content: ""; position: absolute; inset: 0;
  background: var(--cyan); border-radius: 0.75rem;
  transform: translate(1rem, 1rem); z-index: -1;
}

/* Checklist */
.checklist { list-style: none; padding: 0; margin: 0; }
.checklist li {
  position: relative; padding-left: 2rem; margin-bottom: 0.875rem;
  line-height: 1.6;
}
.checklist li::before {
  content: "";
  position: absolute; left: 0; top: 0.35em;
  width: 1.125rem; height: 1.125rem;
  background: var(--cyan);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center/contain no-repeat;
}
.checklist--warn li::before { background: var(--alert); }

/* FAQ accordion */
.faq-item { border-bottom: 1px solid var(--line); }
.faq-trigger {
  width: 100%; display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.5rem; padding: 1.375rem 0;
  background: none; border: 0; cursor: pointer;
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 1.0625rem; font-weight: 600; color: var(--navy);
  text-align: left; line-height: 1.45;
}
.faq-trigger:hover { color: var(--cyan); }
.faq-icon { flex: none; width: 1.5rem; height: 1.5rem; transition: transform 0.3s ease; color: var(--cyan); margin-top: 0.125rem; }
.faq-trigger[aria-expanded="true"] .faq-icon { transform: rotate(45deg); }
.faq-panel { overflow: hidden; max-height: 0; transition: max-height 0.35s ease; }
.faq-panel > div { padding: 0 0 1.5rem; color: var(--ink); line-height: 1.7; max-width: 62ch; }

/* Diagonal stripe pattern for the emergency band */
.stripes-diag {
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255,255,255,0.09) 0px,
    rgba(255,255,255,0.09) 20px,
    transparent 20px,
    transparent 40px
  );
}

/* --------------------------------------------------------------------------
   Data table — spec tables on service and landing pages
   --------------------------------------------------------------------------
   The table carries its own surface AND its own text colour. It must not
   inherit either from the section around it.

   Dropped into a `bg-navy text-white` section without this, every row broke in
   one of two ways: striped rows painted themselves #FAFCFD but kept the
   inherited white text (white on white), while unstriped rows stayed
   transparent so any cell marked `text-navy` sat navy on navy. Either way half
   of each row disappeared.

   Setting background + color here means the table renders as the same light
   card on any section background, light or dark.
   -------------------------------------------------------------------------- */
.data-table {
  width: 100%; border-collapse: collapse; font-size: 0.9375rem;
  background: #fff; color: var(--ink);
}
.data-table thead th {
  background: #EAEFF1; color: var(--navy);
  font-family: "Plus Jakarta Sans", sans-serif; font-weight: 700;
  text-align: left; padding: 0.875rem 1rem; white-space: nowrap;
  border-bottom: 1px solid var(--line);
}
.data-table tbody th[scope="row"] {
  color: var(--navy);
  font-family: "Plus Jakarta Sans", sans-serif; font-weight: 700;
  text-align: left; padding: 0.875rem 1rem; vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.data-table td { padding: 0.875rem 1rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.data-table tbody tr:nth-child(odd)  { background: #fff; }
.data-table tbody tr:nth-child(even) { background: #FAFCFD; }
.data-table tbody tr:hover { background: #F1F7FA; }

/* Wide content must scroll inside its own container, never the page body */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--line); border-radius: 0.75rem; }
.table-scroll .data-table { min-width: 640px; }

/* --------------------------------------------------------------------------
   TABLES ON MOBILE — stack each row into its own card
   --------------------------------------------------------------------------
   Horizontal scrolling looks fine until you actually use it: scroll right and
   the row header slides out of view, leaving values with nothing to identify
   them ("80–100 mm · Fresh food, dairy" — of which room?).

   Below 768px each row becomes a card: the row header is the card title, and
   every value is paired with its column name via data-label. Nothing scrolls,
   nothing loses context.

   Selectors are one level deeper than `.prose td` so the article table on the
   blog inherits this rather than the prose border styling.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

  .table-scroll { border: 0; border-radius: 0; overflow: visible; }
  .table-scroll .data-table { min-width: 0; }

  /* Column headers are read out by the data-label on each cell instead —
     hide them visually but keep them for assistive tech. */
  .data-table thead {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }

  .data-table,
  .data-table tbody,
  .data-table tbody tr { display: block; width: 100%; }

  .data-table tbody tr {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 0.75rem;
    margin-bottom: 0.75rem;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(15,23,42,0.05);
  }
  .data-table tbody tr:last-child { margin-bottom: 0; }
  .data-table tbody tr:nth-child(even) { background: #fff; }
  .data-table tbody tr:hover { background: #fff; }

  /* Row header becomes the card title */
  .data-table tbody th[scope="row"] {
    display: block;
    width: 100%;
    background: #EAEFF1;
    color: var(--navy);
    font-family: "Plus Jakarta Sans", system-ui, sans-serif;
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1.35;
    padding: 0.75rem 1rem;
    border: 0;
    border-bottom: 1px solid var(--line);
    white-space: normal;
  }

  /* Each value sits beside its column name */
  .data-table tbody td {
    display: grid;
    grid-template-columns: minmax(6.5rem, 38%) 1fr;
    align-items: start;
    gap: 0.5rem 0.875rem;
    padding: 0.625rem 1rem;
    border: 0;
    border-bottom: 1px solid #EEF3F6;
    font-size: 0.875rem;
    line-height: 1.5;
  }
  .data-table tbody td:last-child { border-bottom: 0; }

  .data-table tbody td::before {
    content: attr(data-label);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-muted);
    line-height: 1.5;
    padding-top: 0.1rem;
  }
  /* Comparison tables have an empty first column header — no label to show */
  .data-table tbody td:not([data-label])::before,
  .data-table tbody td[data-label=""]::before { content: none; }
  .data-table tbody td:not([data-label]),
  .data-table tbody td[data-label=""] { display: block; }
}

/* Forms */
.field-label { display: block; font-size: 0.875rem; font-weight: 600; color: var(--navy); margin-bottom: 0.375rem; }
.field {
  width: 100%; padding: 0.75rem 1rem;
  border: 1px solid #CBD5E1; border-radius: 0.5rem;
  font-family: inherit; font-size: 1rem; color: var(--navy);
  background: #fff; transition: border-color 0.2s, box-shadow 0.2s;
}
.field::placeholder { color: #94A3B8; }
.field:focus { outline: none; border-color: var(--cyan); box-shadow: 0 0 0 3px rgba(0,168,204,0.15); }
.field[aria-invalid="true"] { border-color: var(--alert); }
.field-error { display: none; margin-top: 0.3rem; font-size: 0.8125rem; color: var(--alert); font-weight: 500; }
.field-error.is-visible { display: block; }
select.field { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2364748B'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 1.25rem; padding-right: 2.5rem; }
textarea.field { min-height: 7rem; resize: vertical; }

/* Two-column form layout.
   Landing-page forms carry 6–8 fields. Stacked in one column inside a hero card
   that produces a very tall form, and the submit button falls below the fold.
   Pairing the short text inputs cuts the height by roughly 40% without
   shrinking any control. Fields that need the full width — long-option selects,
   textareas — opt out with .field-full. */
.form-grid { display: grid; gap: 0.875rem 1rem; }
@media (min-width: 640px) {
  .form-grid { grid-template-columns: 1fr 1fr; }
  .form-grid .field-full { grid-column: 1 / -1; }
}

.form-note {
  padding: 0.75rem 1rem; border-radius: 0.5rem;
  background: #FEF3C7; border: 1px solid #FDE68A;
  color: #92400E; font-size: 0.8125rem; line-height: 1.5;
}

/* Prose — blog articles and long-form legal copy */
.prose { color: var(--ink); font-size: 1.0625rem; line-height: 1.75; max-width: 70ch; }
.prose > * + * { margin-top: 1.25rem; }
/* The :not() guard matters.
   These are element selectors, so they outrank a utility class like text-white
   — and styles.css loads after Tailwind, so the utility cannot win on order
   either. An imported call-to-action block with a navy background and a
   `text-white` heading therefore rendered navy-on-navy: the heading was there,
   sized and spaced correctly, and completely invisible.
   An element that names its own colour keeps it. */
.prose h2:not([class*="text-"]) { color: var(--navy); }
.prose h3:not([class*="text-"]) { color: var(--navy); }
.prose h2 { font-family: "Plus Jakarta Sans", sans-serif; font-size: 1.75rem; font-weight: 700; margin-top: 2.75rem; line-height: 1.25; letter-spacing: -0.01em; }
.prose h3 { font-family: "Plus Jakarta Sans", sans-serif; font-size: 1.25rem; font-weight: 600; margin-top: 2rem; }
.prose ul, .prose ol { padding-left: 1.35rem; }
.prose li { margin-bottom: 0.5rem; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
/* Buttons are excluded. Body-copy links should be cyan and underlined; a
   call-to-action button inside an imported article should keep the colour its
   own variant gives it. Without :not(.btn) the white label on a primary button
   was repainted cyan and underlined. */
.prose a:not(.btn) { color: var(--cyan-hover); text-decoration: underline; text-underline-offset: 2px; }
.prose a:not(.btn):hover { color: var(--cyan); }
.prose strong { color: var(--navy); font-weight: 600; }
.prose blockquote {
  border-left: 4px solid var(--cyan); padding: 0.25rem 0 0.25rem 1.25rem;
  color: var(--navy); font-size: 1.125rem;
}
.prose table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.prose th, .prose td { border: 1px solid var(--line); padding: 0.625rem 0.875rem; text-align: left; }
.prose th { background: #EAEFF1; font-weight: 600; color: var(--navy); }

/* --------------------------------------------------------------------------
   ARTICLE SIDEBAR
   -------------------------------------------------------------------------- */

.article-aside {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
@media (min-width: 1024px) {
  .article-aside {
    position: sticky;
    top: calc(var(--header-h) + 1.5rem);
  }
}

.side-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  padding: 1.375rem;
}

.side-card__title {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--cyan);
  margin: 0 0 0.875rem;
}

/* Table of contents */
.toc-list {
  max-height: 17rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.toc-list a {
  display: block;
  padding: 0.4rem 0.5rem 0.4rem 0.875rem;
  border-left: 2px solid var(--line);
  font-size: 0.875rem;
  line-height: 1.45;
  color: #64748B;
  text-decoration: none;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.toc-list a:hover {
  color: var(--cyan);
  border-left-color: var(--cyan);
}
.toc-list a.is-active {
  color: var(--navy);
  font-weight: 600;
  border-left-color: var(--cyan);
  background: linear-gradient(90deg, rgba(0,168,204,0.08), transparent);
}

/* Sidebar link lists */
.side-links { list-style: none; padding: 0; margin: 0; }
.side-links li + li { margin-top: 0.25rem; }
.side-links a {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--navy);
  text-decoration: none;
  transition: color 0.2s, gap 0.2s;
}
.side-links a:hover { color: var(--cyan); gap: 0.875rem; }
.side-links .material-symbols-outlined { font-size: 19px; color: var(--cyan); flex: none; }

/* Sidebar article cards */
.side-post {
  display: block;
  padding: 0.75rem 0;
  text-decoration: none;
  border-top: 1px solid var(--line);
}
.side-post:first-of-type { border-top: 0; padding-top: 0; }
.side-post span {
  display: block;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cyan);
  margin-bottom: 0.2rem;
}
.side-post p {
  margin: 0;
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--navy);
  transition: color 0.2s;
}
.side-post:hover p { color: var(--cyan); }

/* CTA + emergency variants */
.side-card--cta {
  background: linear-gradient(150deg, #0F172A, #1E293B);
  border-color: transparent;
  color: #fff;
}
.side-card--cta .side-card__title { color: var(--cyan-light); }
.side-card--cta p { color: rgba(255,255,255,0.78); }

.side-card--alert {
  background: rgba(225,29,72,0.05);
  border-color: rgba(225,29,72,0.25);
}

/* --------------------------------------------------------------------------
   TRUST BAR — sector strip between the hero and the first dark section
   --------------------------------------------------------------------------
   Sits between two dark bands, so it needs its own definition rather than
   floating as loose centred text. A soft top-to-bottom wash lifts it off the
   page, and hairline rules top and bottom seal it against the sections either
   side. */
.trust-bar {
  padding: 2.75rem 0 3rem;
  background: linear-gradient(180deg, #FFFFFF 0%, #EFF4F7 100%);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.7rem;
}

.trust-item__icon {
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 1px solid var(--line);
  color: var(--cyan);
  box-shadow: 0 1px 3px rgba(15,23,42,0.06);
  transition: background 0.25s ease, color 0.25s ease,
              border-color 0.25s ease, transform 0.25s ease;
}
.trust-item__icon .material-symbols-outlined { font-size: 24px; }

.trust-item:hover .trust-item__icon {
  background: var(--cyan);
  border-color: var(--cyan);
  color: #fff;
  transform: translateY(-3px);
}

.trust-item__label {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--navy);
  max-width: 11rem;
}

@media (min-width: 640px) {
  .trust-item__label { font-size: 0.875rem; }
}

/* --------------------------------------------------------------------------
   PROJECT LIGHTBOX
   -------------------------------------------------------------------------- */

/* Card trigger — covers the whole card so the entire tile is clickable, and
   gives keyboard users a real focus target (an <article> isn't focusable). */
.proj-trigger {
  position: absolute;
  inset: 0;
  width: 100%;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  border-radius: inherit;
}
.proj-trigger__icon {
  position: absolute;
  top: 5.5rem;                      /* centred on the 14rem image area */
  left: 50%;
  transform: translate(-50%, -50%) scale(0.8);
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  background: var(--cyan);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
  box-shadow: 0 6px 18px rgba(15,23,42,0.28);
}
.proj:hover .proj-trigger__icon,
.proj-trigger:focus-visible .proj-trigger__icon {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.proj-trigger:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* Dialog */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.lightbox[hidden] { display: none; }

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(8, 13, 26, 0.82);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.28s ease;
}
.lightbox.is-open .lightbox__backdrop { opacity: 1; }

.lightbox__panel {
  position: relative;
  width: min(1080px, 100%);
  max-height: calc(100vh - 2rem);
  background: #fff;
  border-radius: 1rem;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto 1fr;
  opacity: 0;
  transform: translateY(14px) scale(0.985);
  transition: opacity 0.28s ease, transform 0.28s ease;
  box-shadow: 0 30px 70px rgba(0,0,0,0.45);
}
.lightbox.is-open .lightbox__panel { opacity: 1; transform: none; }

@media (min-width: 900px) {
  .lightbox__panel { grid-template-rows: none; grid-template-columns: 1.45fr 1fr; }
}

/* Image — contained, never cropped, on a dark mat */
.lightbox__media {
  margin: 0;
  background: #0B1220;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 14rem;
  max-height: 45vh;
}
@media (min-width: 900px) {
  .lightbox__media { max-height: calc(100vh - 2rem); }
}
.lightbox__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.lightbox__body {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
}
@media (min-width: 900px) { .lightbox__body { padding: 2rem; } }

.lightbox__cat {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cyan);
  margin-bottom: 0.5rem;
}
.lightbox__title {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--navy);
  margin: 0 0 0.875rem;
}
.lightbox__desc {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--ink);
  margin: 0 0 1.5rem;
}

.lightbox__foot { margin-top: auto; padding-top: 1.25rem; border-top: 1px solid var(--line); }

.lightbox__pager { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; }
.lightbox__nav {
  width: 2.5rem; height: 2.5rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--navy);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}
.lightbox__nav:hover:not(:disabled) { background: var(--cyan); border-color: var(--cyan); color: #fff; }
.lightbox__nav:disabled { opacity: 0.35; cursor: default; }
.lightbox__count { font-size: 0.8125rem; font-weight: 600; color: var(--ink-muted, #64748B); }

.lightbox__cta { display: flex; flex-wrap: wrap; gap: 0.625rem; }

.lightbox__close {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  z-index: 3;
  width: 2.5rem; height: 2.5rem;
  border-radius: 999px;
  border: 0;
  background: rgba(15,23,42,0.65);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.2s ease;
}
.lightbox__close:hover { background: var(--alert); }

body.lightbox-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .lightbox__backdrop, .lightbox__panel { transition: none; }
}

/* Mobile navigation drawer */
.nav-drawer {
  position: fixed; inset: 0 0 0 auto;
  width: min(88vw, 22rem); z-index: 120;
  background: #fff;
  transform: translateX(100%);
  transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
  overflow-y: auto;
  box-shadow: -8px 0 32px rgba(15,23,42,0.18);
}
.nav-drawer.is-open { transform: translateX(0); }
.nav-scrim {
  position: fixed; inset: 0; z-index: 110;
  background: rgba(15,23,42,0.5);
  opacity: 0; pointer-events: none;
  transition: opacity 0.3s ease;
}
.nav-scrim.is-open { opacity: 1; pointer-events: auto; }
body.nav-open { overflow: hidden; }

/* Sticky mobile action bar — landing pages */
.action-bar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 90;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: var(--navy);
  border-top: 1px solid rgba(255,255,255,0.12);
  padding-bottom: env(safe-area-inset-bottom);
}
.action-bar a {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.2rem; min-height: 3.75rem; padding: 0.5rem;
  color: #fff; text-decoration: none;
  font-size: 0.75rem; font-weight: 600;
}
.action-bar a + a { border-left: 1px solid rgba(255,255,255,0.12); }
.action-bar a:active { background: rgba(255,255,255,0.08); }
@media (min-width: 1024px) { .action-bar { display: none; } }

/* Floating WhatsApp.
   Expands on hover to name itself — a bare green circle relies on the visitor
   recognising the glyph, and the label costs nothing when collapsed. */
.wa-float {
  position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 95;
  height: 3.5rem;
  min-width: 3.5rem;
  padding: 0 1rem;
  border-radius: 999px;
  background: #25D366; color: #fff;
  display: flex; align-items: center; justify-content: center; gap: 0;
  box-shadow: 0 8px 24px rgba(37,211,102,0.4);
  transition: transform 0.3s ease, box-shadow 0.3s ease, gap 0.3s ease;
  overflow: hidden;
  white-space: nowrap;
}
.wa-float:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(37,211,102,0.5); }

.wa-float__label {
  max-width: 0;
  opacity: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  transition: max-width 0.32s ease, opacity 0.25s ease;
}
@media (min-width: 1024px) and (hover: hover) {
  .wa-float:hover  .wa-float__label,
  .wa-float:focus-visible .wa-float__label { max-width: 12rem; opacity: 1; }
  .wa-float:hover, .wa-float:focus-visible { gap: 0.625rem; }
}

/* Pages with a sticky action bar already offer WhatsApp there. Show the float
   only from 1024px up, where the action bar is hidden. */
.wa-float--with-bar { display: none; }
@media (min-width: 1024px) {
  .wa-float--with-bar { display: flex; }
}

/* Hero shader canvas */
.shader-canvas { display: block; width: 100%; height: 100%; }

/* --------------------------------------------------------------------------
   5. MOTION & PRINT
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
}

@media print {
  .site-header, .site-footer, .wa-float, .action-bar,
  .nav-drawer, .nav-scrim, .no-print { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .reveal { opacity: 1 !important; transform: none !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
  .faq-panel { max-height: none !important; }
  section { break-inside: avoid; }
}

/* ==========================================================================
   WORDPRESS THEME ADDITIONS
   Rules the static build did not need. Everything above this line is carried
   over from the static site unchanged.
   ========================================================================== */

/* Honeypot.
   Hidden with CSS rather than type="hidden" or [hidden] — both are trivially
   detected and skipped by a bot that parses the form. Kept out of the
   accessibility tree and the tab order too, so nobody using a screen reader or
   a keyboard can land in a field they cannot see and must not fill. */
.chillex-hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Form card wrapper — the static markup used .card directly; this adds only
   the sticky behaviour the landing hero form needs beside long copy. */
.form-card { position: relative; }

@media (min-width: 1024px) {
  .is-landing .form-card { position: sticky; top: 6.5rem; }
}

/* Submission status line. role="status" is announced on change, so this must
   stay in the document even when empty rather than being toggled with
   display:none, which some screen readers treat as a new region. */
.form-status {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  min-height: 1.25rem;
}
.form-status:empty { margin-top: 0; min-height: 0; }
.form-status--error { color: var(--alert); font-weight: 600; }
.form-status--ok { color: #0f766e; font-weight: 600; }

/* Field error state, set by the client-side validator. */
.field.is-invalid { border-color: var(--alert); }
.field.is-invalid:focus { outline-color: var(--alert); }

/* Project filter buttons — active state. */
.filter-btn { transition: border-color 200ms, background 200ms, color 200ms; }
.filter-btn.is-active {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}
.filter-btn:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* A project hidden by the filter. */
.proj[hidden] { display: none; }

/* Blog sidebar table of contents. */
.toc { list-style: none; margin: 0; padding: 0; font-size: 0.875rem; }
.toc li { margin-bottom: 0.5rem; }
.toc li.toc--h3 { padding-left: 0.875rem; }
.toc a { color: var(--ink); text-decoration: none; line-height: 1.45; display: block; }
.toc a:hover { color: var(--cyan); }
.toc a.is-current { color: var(--cyan); font-weight: 600; }

/* Pagination. */
.pagination { display: flex; justify-content: center; }
.pagination .nav-links { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.pagination .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.5rem; height: 2.5rem; padding: 0 0.75rem;
  border: 1px solid var(--line); border-radius: 0.5rem;
  background: #fff; color: var(--navy);
  font-weight: 600; font-size: 0.875rem; text-decoration: none;
}
.pagination .page-numbers:hover { border-color: var(--cyan); color: var(--cyan); }
.pagination .page-numbers.current { background: var(--navy); border-color: var(--navy); color: #fff; }

/* Designer / developer credit.
   Sits in the footer bottom bar. Deliberately quieter than the client's own
   legal links — it should be findable, not competing with them. */
.chillex-credit { margin: 0; }
.chillex-credit__link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,0.25);
  transition: color 200ms, border-color 200ms;
}
.chillex-credit__link:hover,
.chillex-credit__link:focus-visible {
  color: var(--cyan-light, #58D5FB);
  border-bottom-color: currentColor;
}

/* --------------------------------------------------------------------------
   COMPONENT MODIFIERS

   styles.css loads *after* the compiled Tailwind, so a utility like bg-navy
   cannot override a component like .card — the component always wins on load
   order. Putting `class="card bg-navy text-white"` on the blog sidebar CTA
   therefore produced white text on a white card, invisible.

   The fix is a real modifier rather than fighting the cascade. Same lesson as
   .data-table: a component that paints its own background must also state its
   own text colour.
   -------------------------------------------------------------------------- */
.card--dark {
  background: var(--navy);
  color: rgba(255,255,255,0.75);
  border-color: rgba(255,255,255,0.1);
}
.card--dark h2,
.card--dark h3 { color: #fff; }

/* Buttons inside prose keep their button styling.
   .prose a underlines every link, which is right for body copy and wrong for
   a call-to-action button sitting inside an imported article. */

/* Blog featured image.
   Several of the source photographs are tall portraits (740×1600). Without a
   cap the lead image pushed the article itself below the fold. */
.post-hero {
  max-height: 30rem;
  width: 100%;
  object-fit: cover;
  object-position: center;
}

/* A project filtered out of view. The lightbox reads the same class to decide
   which projects are in the browsable set, so paging skips hidden ones. */
.proj.is-hidden { display: none; }
