/* ===================================================================
   RESPONSIVE LAYER — Deep Learner Academy
   -------------------------------------------------------------------
   Loaded LAST on every page, after each page's own stylesheet(s).

   Purpose: make the existing design work on every screen size without
   changing the design itself. Nothing here introduces new colours,
   fonts, shadows or motion — it only removes rigid sizing, keeps
   content inside the viewport, and enlarges touch targets on
   touch devices.

   Target widths: 320, 360, 375, 390, 414, 480, 600, 768, 820,
                  1024, 1280, 1366, 1440, 1600, 1920, 2560.

   Section index
     1.  Viewport & overflow guard
     2.  Fluid media (img / video / iframe / svg / canvas)
     3.  Fluid containers
     4.  Header / navigation
     5.  Grid & flex de-rigidifying
     6.  Legal pages (privacy / terms)
     7.  Tables
     8.  Forms & buttons
     9.  Modals, popups & overlays
     10. Fixed-format documents (invoice / certificate)
     11. Touch targets & coarse-pointer affordances
     12. Typography floors
     13. Very small phones (<=360px)
     14. Large & ultra-wide displays
     15. Landscape phones
     16. Motion & accessibility preservation
   =================================================================== */


/* ===================================================================
   1. VIEWPORT & OVERFLOW GUARD
   Stops any single element from creating a horizontal scrollbar.
   `overflow-x: clip` is used rather than `hidden` so that
   `position: sticky` descendants (the legal TOC, dashboard topbars)
   keep working — `hidden` would silently turn them into scroll
   containers and break stickiness.
   =================================================================== */
html {
  overflow-x: clip;
  /* Prevent iOS/Android from inflating text after an orientation change */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  overflow-x: clip;
  max-width: 100%;
}

/* Long unbroken strings (URLs, IDs, certificate codes, emails) must
   wrap instead of pushing the layout wider than the screen. */
p, li, td, th, dd, dt, figcaption,
h1, h2, h3, h4, h5, h6,
.legal-prose a, .footer-link, code, pre {
  overflow-wrap: break-word;
  word-wrap: break-word;
}


/* ===================================================================
   2. FLUID MEDIA  —  declared inside a cascade layer
   -------------------------------------------------------------------
   These are *defaults*, not overrides. They live in `@layer dla-base`
   because unlayered styles always beat layered ones regardless of
   specificity or source order — so every explicit size the design
   already sets (the 40px nav logo, avatars, icons) keeps winning,
   while any image that was never given a size still gets the
   responsive treatment.

   This is what makes the layer necessary: responsive.css loads last,
   so without it a blanket `img { height: auto }` would silently
   flatten authored image dimensions site-wide.
   =================================================================== */
@layer dla-base {
  img, video, canvas, svg:not([width]) {
    max-width: 100%;
  }

  img, video {
    height: auto;
  }

  /* Responsive embeds — YouTube/Vimeo iframes */
  iframe {
    max-width: 100%;
  }

  iframe[src*="youtube"],
  iframe[src*="vimeo"],
  iframe[src*="player"] {
    width: 100%;
    aspect-ratio: 16 / 9;
    height: auto;
  }
}

/* Full-bleed background/hero media needs no override here: because the
   defaults above are layered, the sizing these elements already carry
   in styles.css and the dashboards' inline CSS wins automatically. An
   explicit `max-width: none` was removed after it measured 4px wider
   than the design intends on the home hero. */


/* ===================================================================
   3. FLUID CONTAINERS
   The site's containers already use max-width; only their fixed side
   padding needed to become fluid so narrow phones keep usable gutters
   without wasting screen width.
   =================================================================== */
/* NOTE: no `width: 100%` here. These containers are block elements
   that already fill their parent, but several heroes place them
   inside a flex row where `width: 100%` would defeat the
   shrink-to-fit sizing the design relies on (it left-aligned the
   hero copy at 1280px instead of centring it). `max-width` alone
   gives the fluid behaviour without that side effect. */

/* Fluid gutters are applied only below 1100px — the width at which
   styles.css already switches these containers to a fixed 24px pad.
   Replacing that step with a clamp keeps gutters proportional from
   320px up, while every layout at 1100px and wider keeps the exact
   padding the design specifies (including .container's intentional
   zero side padding at desktop). */
@media (max-width: 1100px) {
  .container,
  .container-wide,
  .container-courses {
    padding-inline: clamp(16px, 4.5vw, 24px);
  }
}

/* A grid/flex child must be allowed to shrink below its content's
   intrinsic minimum, otherwise a wide descendant (table, long word,
   pre) forces the whole column wider than the screen. This is the
   single most common cause of horizontal scroll on this site. */
.container > *,
.container-wide > *,
.container-courses > * {
  min-width: 0;
}


/* ===================================================================
   4. HEADER / NAVIGATION
   The hamburger menu and its behaviour already exist in styles.css
   (collapse at 1100px). These rules only stop the brand lockup from
   pushing the toggle button off-screen on small handsets.
   =================================================================== */
.nav-inner {
  gap: 12px;
  min-width: 0;
}

.nav-brand {
  min-width: 0;
  flex-shrink: 1;
}

.nav-brand-main {
  min-width: 0;
}

.nav-brand-text {
  min-width: 0;
}

/* The toggle is the one thing that must never shrink or clip */
.nav-toggle {
  flex-shrink: 0;
}

.nav-cta {
  flex-shrink: 0;
  min-width: 0;
}

@media (max-width: 480px) {
  /* Scale the brand lockup down proportionally rather than letting it
     overflow. Wordmark keeps its font, weight and colour. */
  .nav-brand-main {
    gap: 7px;
    margin: 8px 0;
  }

  .nav-logo-img {
    height: 32px;
    min-width: 32px;
  }

  .nav-brand-divider {
    height: 34px;
  }

  .nav-brand-line {
    font-size: 14px;
  }

  /* The long second line ("Deep Learner Academy") truncates instead of
     forcing the row wider than the screen. */
  .nav-brand-line + .nav-brand-line {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
  }

  .nav-brand-tag {
    font-size: 9.5px;
  }
}


/* ===================================================================
   4b. INLINE-STYLED GRIDS
   -------------------------------------------------------------------
   Several sections set `grid-template-columns` in a style="" attribute
   directly in the HTML. An inline declaration outranks every stylesheet
   rule, so no media query can reach it — those sections stayed
   multi-column all the way down to 320px. The worst case was the
   "Why Us" heading on index.html, whose column collapsed to 116px and
   broke "institutions." across two lines mid-word.

   `!important` is the only thing that beats an inline style, so it is
   used deliberately and is scoped to small screens only — desktop
   still uses the inline value exactly as authored.

   Each selector matches the literal text of a style attribute, so this
   list is exhaustive for the patterns actually present in the markup
   (verified with a sweep of every HTML file). Ratio and fixed-column
   layouts collapse; `auto-fill`/`auto-fit` tracks are left alone
   because they already reflow, as are `auto`-based rows such as
   `auto 1fr auto`, which are alignment helpers rather than columns.
   =================================================================== */
@media (max-width: 768px) {
  [style*="grid-template-columns:0.8fr 1fr"],
  [style*="grid-template-columns:0.7fr 1fr"],
  [style*="grid-template-columns:1.15fr 1fr"],
  [style*="grid-template-columns: 1.6fr 1fr"],
  [style*="grid-template-columns: 1fr 1fr"],
  [style*="grid-template-columns:1fr 1fr"],
  [style*="grid-template-columns: 1fr 296px"],
  [style*="grid-template-columns:2fr 1.4fr .8fr auto"],
  [style*="grid-template-columns: repeat(4, 1fr)"],
  [style*="grid-template-columns:repeat(3,1fr)"],
  [style*="grid-template-columns:repeat(3,minmax(0,1fr))"],
  [style*="grid-template-columns:repeat(7,1fr)"] {
    grid-template-columns: 1fr !important;
    /* The authored desktop gap (often 80px) is far too large once the
       columns are stacked — it reads as a broken page. */
    gap: 24px !important;
  }
}

/* Tablet: 3- and 4-up card rows step down to two columns before
   collapsing entirely, rather than jumping straight to one. */
@media (min-width: 769px) and (max-width: 1024px) {
  [style*="grid-template-columns: repeat(4, 1fr)"],
  [style*="grid-template-columns:repeat(7,1fr)"] {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}


/* ===================================================================
   4c. "YOUR JOURNEY" STEPPER (index.html)
   -------------------------------------------------------------------
   This section shipped with no responsive rules at all: `.jrny-tabs`
   held `repeat(6, 1fr)` at every width, so on a 390px phone the six
   step buttons were 46px wide each, and `.jrny-panel` stayed two
   columns. Both are given breakpoints here; the desktop layout is
   untouched.
   =================================================================== */
/* Explicit column counts rather than auto-fit: there are exactly six
   steps, and only divisors of six (3 and 2) fill the last row. auto-fit
   produced a five-across row at 600px with a single orphaned tile. */
@media (max-width: 900px) {
  .jrny-tabs {
    grid-template-columns: repeat(3, 1fr);   /* 3 + 3 */
    gap: 10px;
  }

  .jrny-tab {
    padding: 14px 6px;
  }
}

@media (max-width: 560px) {
  .jrny-tabs {
    grid-template-columns: repeat(2, 1fr);   /* 2 + 2 + 2 */
  }
}

@media (max-width: 768px) {
  /* Copy above, illustration below — the same reading order as
     desktop, just stacked. */
  .jrny-panel {
    grid-template-columns: 1fr;
  }

  .jrny-panel-left {
    padding: 32px 24px;
  }

  .jrny-panel-right {
    padding: 32px 24px;
    gap: 20px;
  }
}


/* ===================================================================
   5. GRID & FLEX DE-RIGIDIFYING
   Fixed column counts are converted to auto-fitting tracks so cards
   reflow naturally instead of squashing. Column counts at desktop
   width are unchanged — auto-fit resolves to the same count once
   there is room for it.
   =================================================================== */

/* Any grid item may shrink below its intrinsic content width */
[class*="grid"] > * {
  min-width: 0;
}

@media (max-width: 1024px) {
  .svc-grid,
  .fmt-grid,
  .team-comp-grid,
  .case-stats-grid,
  .prog-grid,
  .principle-grid,
  .training-cards {
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  }
}

@media (max-width: 600px) {
  /* Below 600px every card grid becomes a single column — matches the
     "cards stack vertically" requirement. */
  .svc-grid,
  .fmt-grid,
  .team-comp-grid,
  .case-stats-grid,
  .prog-grid,
  .principle-grid,
  .training-cards,
  .courses-grid {
    grid-template-columns: 1fr;
  }

  /* Flex rows wrap instead of overflowing */
  .footer-legal-links,
  .legal-contact-rows,
  .nav-menu-ctas,
  .hero-actions,
  .cta-row {
    flex-wrap: wrap;
  }
}


/* ===================================================================
   6. LEGAL PAGES (privacy.html / terms.html)
   Root cause of horizontal scroll: `.legal-table` carries
   min-width: 480px. Because `.legal-table-wrap` had no min-width
   floor of its own, that 480px propagated up as the min-content size
   of the `1fr` grid column, forcing the whole page to 494px wide on a
   320px screen. Capping the floor at 0 lets the wrapper scroll the
   table horizontally, as intended, while the page stays in-viewport.
   =================================================================== */
.legal-layout {
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
}

.legal-toc,
.legal-prose,
.legal-table-wrap,
.legal-prose > section {
  min-width: 0;
}

.legal-table-wrap {
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
}

@media (max-width: 1024px) {
  .legal-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}


/* ===================================================================
   7. TABLES
   Tables keep their desktop layout and become horizontally scrollable
   inside a wrapper on narrow screens. `js/responsive.js` adds the
   `.table-scroll` wrapper to any table that does not already sit in
   one (the legal tables already have `.legal-table-wrap`).
   =================================================================== */
.table-scroll {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Hint that there is more content sideways, without adding chrome */
  overscroll-behavior-x: contain;
}

.table-scroll > table {
  margin-inline: 0;
}


/* ===================================================================
   8. FORMS & BUTTONS
   =================================================================== */
/* Controls must never be wider than their container (unlayered — this
   is a fix). The typeface default is layered so any control the design
   already styles keeps its own font. */
input, select, textarea, button {
  max-width: 100%;
}

@layer dla-base {
  input, select, textarea, button {
    font-family: inherit;
  }
}

/* iOS zooms the page in when a focused input's text is under 16px.
   Bumping only the control's own font size avoids that without
   touching any other typography. */
@media (max-width: 768px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea {
    font-size: max(16px, 1em);
  }
}

@media (max-width: 600px) {
  /* Inputs fill the available width */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="submit"]):not([type="button"]),
  select,
  textarea {
    width: 100%;
  }

  /* Form grids collapse to one column */
  .form-grid,
  .contact-form-grid,
  .apply-form-grid {
    grid-template-columns: 1fr;
  }

  .form-field.span-2 {
    grid-column: span 1;
  }

  /* Primary/secondary actions go full width so they are easy to hit.
     Inline links, nav buttons, icon buttons and carousel controls are
     excluded so the header and sliders keep their compact layout. */
  .btn:not(.btn-icon):not(.nav-toggle):not(.btn-inline):not(.showcase-dot):not(.showcase-watch),
  button[type="submit"],
  input[type="submit"] {
    width: 100%;
  }

  /* ...but buttons sitting side by side in a wrapping row keep sharing
     the row rather than each taking a full line. */
  .btn-row .btn,
  .hero-actions .btn,
  .nav-menu-ctas .btn {
    width: auto;
    flex: 1 1 auto;
  }
}


/* ===================================================================
   9. MODALS, POPUPS & OVERLAYS
   Dialogs must never exceed the viewport or trap content off-screen,
   and must scroll internally when the content is taller than the
   screen (common on short landscape phones).
   =================================================================== */
.modal,
.modal-panel,
.modal-content,
.notify-modal,
.notify-modal-panel,
.popup,
.popup-panel,
[role="dialog"] {
  max-width: min(100% - 24px, 560px);
  max-height: calc(100dvh - 24px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Older browsers without dvh support fall back to vh */
@supports not (height: 100dvh) {
  .modal,
  .modal-panel,
  .modal-content,
  .notify-modal,
  .notify-modal-panel,
  .popup,
  .popup-panel,
  [role="dialog"] {
    max-height: calc(100vh - 24px);
  }
}

@media (max-width: 480px) {
  .modal,
  .modal-panel,
  .modal-content,
  .notify-modal-panel,
  .popup-panel {
    max-width: calc(100% - 20px);
    border-radius: 14px;
  }
}


/* ===================================================================
   10. FIXED-FORMAT DOCUMENTS (invoice / certificate)
   These are print-proportioned artefacts (720px invoice, 1120x720
   certificate) whose internal layout must not reflow — reflowing them
   would change the printed document. Instead the whole sheet is
   scaled down to fit narrow screens, preserving exact proportions.
   `transform` keeps the print output untouched.
   =================================================================== */
.inv,
.cert {
  max-width: 100%;
}

@media (max-width: 820px) {
  .inv-wrap,
  .cert-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Fluid down-scale: the sheet keeps its aspect ratio and simply gets
     smaller, exactly as a print preview would. */
  .cert {
    transform: scale(min(1, calc((100vw - 32px) / 1120)));
    transform-origin: top left;
    margin-inline: 0;
  }
}

@media (max-width: 768px) {
  .inv {
    width: 100%;
    padding: 32px 20px;
    margin-inline: 0;
  }

  .inv-totals {
    width: 100%;
    max-width: 320px;
  }
}

/* Printing is unaffected by any of the above */
@media print {
  .inv,
  .cert {
    transform: none;
    width: auto;
  }
}


/* ===================================================================
   11. TOUCH TARGETS & COARSE-POINTER AFFORDANCES
   Applied only on touch devices via `pointer: coarse`, so the mouse
   design — including every hover effect — is left exactly as it is.
   Hit areas are grown with padding or a transparent ::after overlay
   rather than by resizing the visible element, so nothing moves.
   =================================================================== */
@media (pointer: coarse) {
  /* Small round icon buttons: keep the painted size, grow the hit area */
  .footer-social-btn,
  .showcase-dot,
  .showcase-watch,
  .slider-dot,
  .carousel-dot,
  .icon-btn {
    position: relative;
  }

  .footer-social-btn::after,
  .showcase-dot::after,
  .showcase-watch::after,
  .slider-dot::after,
  .carousel-dot::after,
  .icon-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: max(100%, 44px);
    height: max(100%, 44px);
    /* Invisible — purely an enlarged tap surface */
    background: transparent;
  }

  /* Text links in lists get comfortable vertical padding */
  .footer-link,
  .legal-toc-link,
  .nav-link {
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  /* Dots sit in a row — keep them from overlapping each other now that
     their hit areas are wider. */
  .showcase-dots,
  .slider-dots,
  .carousel-dots {
    gap: max(12px, 0.75rem);
  }

  /* Hover-only reveals must also respond to tap/focus */
  .card:focus-within,
  .course-card:focus-within,
  .event-card:focus-within {
    /* Mirrors the existing :hover treatment */
    z-index: 1;
  }
}

/* Keyboard focus stays visible everywhere (accessibility preserved) */
:focus-visible {
  outline: 2px solid var(--accent, #1a3a6e);
  outline-offset: 2px;
}


/* ===================================================================
   12. TYPOGRAPHY FLOORS
   The design's existing type scale is kept. These rules only ensure
   headings scale fluidly instead of stepping, and that no body copy
   drops below a legible size on small screens.
   =================================================================== */
/* NOTE: `.ind-cell-title` is deliberately left alone too. styles.css
   promotes it to 30px on phones via the blanket `.display` rule, which
   looked like the cause of a mid-word break — but measuring line boxes
   against word counts at both 22px and 30px shows no break at either
   size. The wide title simply wraps at its spaces, which is correct.

   NOTE: the footer wordmark is deliberately left alone. It stacks
   "Deep" / "Learner" on two lines by design, so its 51px shrink-to-fit
   box is correct, not a squeeze — an automated width check flags it
   only because an inline box *is* the width of its own text. */

/* Micro-copy that measured under 11px on a phone is nudged up to a
   legible floor. Deliberately unlayered — this is an intentional
   accessibility override of the authored size, and it applies only on
   small screens, so the desktop design is untouched. */
@media (max-width: 600px) {
  .trusted-by-label,
  .sec-label,
  .jrny-tab-num,
  .jrny-panel-badge,
  .ind-soon-chip,
  .footer-brand-tag {
    font-size: max(11px, 0.7rem);
  }
}

/* Fluid heading defaults — layered, so any page that already defines
   its own size (several already use clamp()) keeps it. These only
   catch headings that would otherwise step abruptly between
   breakpoints. Each upper bound matches the existing desktop size, so
   nothing changes at desktop width. */
@layer dla-base {
  .hero-title,
  .page-intro-title {
    font-size: clamp(30px, 5.2vw, 60px);
    line-height: 1.1;
  }

  .section-title,
  .sec-title {
    font-size: clamp(24px, 3.6vw, 42px);
    line-height: 1.15;
  }

  /* Body-copy legibility floor on small screens */
  @media (max-width: 600px) {
    p, li, td, th, label {
      line-height: 1.6;
    }
  }
}


/* ===================================================================
   13. VERY SMALL PHONES (<= 360px)
   320px and 360px devices get tighter spacing so content keeps its
   breathing room without overflowing.
   =================================================================== */
@media (max-width: 360px) {
  .container,
  .container-wide,
  .container-courses {
    padding-inline: 14px;
  }

  /* Pills and chips wrap rather than scroll off the edge */
  .legal-toc-links,
  .filter-row,
  .chip-row,
  .tag-row {
    flex-wrap: wrap;
  }

  /* Tab strips become horizontally scrollable instead of clipping */
  .jrny-tabs,
  .tab-strip,
  .tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .jrny-tabs::-webkit-scrollbar,
  .tab-strip::-webkit-scrollbar,
  .tabs::-webkit-scrollbar {
    display: none;
  }

  .jrny-tab,
  .tab-strip > *,
  .tabs > * {
    flex: 0 0 auto;
  }
}


/* ===================================================================
   14. LARGE & ULTRA-WIDE DISPLAYS (1600 / 1920 / 2560)
   The site's 1480px max-width is intentional and is kept. These rules
   only make sure that full-bleed sections, hero art and background
   decoration still cover the screen on very wide monitors instead of
   ending early.
   =================================================================== */
@media (min-width: 1600px) {
  /* Full-bleed backgrounds span the whole viewport */
  .section-full,
  .hero,
  .footer {
    width: 100%;
  }
}

/* The 1480px max-width is a deliberate design decision and is left
   alone at 1600/1920/2560 — the layout simply centres with wider
   margins, which is the intended behaviour. Nothing is overridden
   here; these widths were verified to have no overflow instead. */

@media (min-width: 2560px) {
  /* Cap decorative blur/glow elements so they do not tile or repeat
     awkwardly across a 4K canvas. */
  .why-blob,
  .footer-glow,
  .hero-corner-beam {
    max-width: 100vw;
  }
}


/* ===================================================================
   15. LANDSCAPE PHONES
   Short viewports (phone held sideways) need reduced vertical padding
   or the hero alone fills the screen.
   =================================================================== */
@media (max-height: 520px) and (orientation: landscape) {
  .hero,
  .legal-intro,
  .page-intro {
    padding-block: 88px 40px;
  }

  .hero-title {
    font-size: clamp(24px, 4.5vh, 38px);
  }

  /* The mobile nav panel must scroll rather than run off the bottom */
  .nav-links.open {
    max-height: calc(100dvh - 88px);
    overflow-y: auto;
  }
}


/* ===================================================================
   16. MOTION & ACCESSIBILITY PRESERVATION
   All existing animations are kept as authored. This only honours the
   OS-level reduced-motion preference, which styles.css already
   respects — repeated here so it also covers the pages that carry
   their own inline CSS (dashboards, course player, login).
   =================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
