/* Hero: the map fills the section and the words sit under it (founder 2026-10-18: "Move this down ...
   so the map or globe full the hero section"). Layout only. Nothing is added, removed or renamed, so
   map.js, hero-live.js, map-plus.js and the rest keep working on exactly the same nodes.
   Loaded after hero-clean.css, which still owns how the pieces inside the map look. */

/* One column, map first. Both rows are centred with justify-self, NOT with "margin: 0 auto":
   an auto margin on a grid item cancels the stretch and collapses the column to nothing. */
.hero-grid { grid-template-columns: minmax(0, 1fr) !important; gap: 34px; }
.hero-map { order: -1; justify-self: center !important; margin: 0 !important; width: 100%; }
.hero-copy { order: 0; justify-self: center; margin: 0; width: 100%; }

/* The map spreads to the full width of the container (founder 2026-10-18: "Spread the map to
   the full container width"). No height cap: at 17/10 a full-width panel runs a little past the
   first screen on a short laptop, which is the trade for the width. */
.hero-map { max-width: 100% !important; }

/* ===== The map and its band fit the first screen =====
   Founder 2026-10-18: "Resize everything on the page. No scroll bar should be needed".

   Full container width and fitting the screen pull against each other. A world map at its true
   17/10 shape, 1405px wide, is 827px tall, and the hero starts 169px down the page under the
   notice bar and the header. On a 1440x900 screen that put the bottom of the map 144px past the
   fold, so you had to scroll before you had seen it.

   The map takes the whole first screen (founder 2026-10-18: "Increase the height of the map.
   i WANT IT BIGGER"). The budget was the screen minus everything above the panel AND minus the
   band under it, which held the panel to 525px on a 1440x900 screen. The band is no longer in
   the sum, so the panel runs all the way to the fold: 665px on the same screen, and full
   container width on a 1366 laptop where it used to give up 23% of its width.
   The band now sits just below the fold. That is the trade for the height, and it is the most
   the map can take while still being whole on one screen: anything more and you scroll to see
   the bottom of it.
   Because the map image is object-fit:fill and every marker is positioned in percentages, a
   shorter panel keeps every pin in the right place, it only flattens the picture.

   The height has to be set outright. max-height on its own does NOT work here: with
   aspect-ratio still in force the panel keeps 17/10 and simply shrinks both ways, so the map got
   narrower instead of flatter and ended up at 57% of the container. Setting height and dropping
   aspect-ratio lets the width stay while the picture flattens.

   The height is the smaller of two things: the map's natural height for the current width
   ((100vw - 35px) / 1.7, the container minus its padding), and what is left on the screen. On a
   tall window the first wins and the map keeps its true shape; on a normal laptop the second
   wins and it flattens. Without that min() a tall narrow window would stretch the map upright.

   The width cap stops the flattening going too far: at 2.6x the height the shape holds at or
   under 2.6:1, which still reads as a world map. 1.95, 2.2 and 2.6 were rendered and compared
   before settling on it. With the taller budget it rarely binds now, so the map keeps the full
   container width on every common screen.

   235px is measured, not guessed: 217 to the top of the panel (169 for the notice bar and the
   header, plus the hero's own 40px of padding, plus the panel's offset), and ~18 of breathing
   room so the map stops at the fold rather than exactly on it. */
.hero-map { max-width: 100% !important; }
@media (min-width: 641px) {
  .hero-map:not(.map-fs):not(.mapf-fs):not(.globe-on) {
    max-width: min(100%, calc((100vh - 235px) * 2.6)) !important;
  }
  .hero-map:not(.map-fs):not(.mapf-fs):not(.globe-on) .map-panel {
    aspect-ratio: auto;
    height: min(calc((100vw - 35px) / 1.7), calc(100vh - 235px));
    max-height: none;
  }
}

/* The globe is square, so it needs its own cap to stay on the screen. */
.hero-map.globe-on { max-width: min(100%, 86vh) !important; }

/* Full screen is the one place the cap must not apply: there the map should take the whole
   screen. Kept as three separate rules so an unknown selector cannot drop the others. */
.hero-map.map-fs { max-width: none !important; }
.hero-map.mapf-fs { max-width: none !important; }
.hero-map:fullscreen { max-width: none !important; }
.hero-map:-webkit-full-screen { max-width: none !important; }

/* ============================================================================
   The words below the map.

   Narrow screens get one centred column. From 1000px the band splits in two:
   what the Academy offers on the left, the way in on the right.

   The reason for the split is reading order. In the HTML the announcement card
   comes first, so centred in one column it sat above the headline and a visitor
   met a box before they met the promise. In two columns the left is read first,
   so the headline leads and the card becomes what it should be, the panel you
   act on, holding every way in: sign up, sign in, Windows, Mac.
   ============================================================================ */

/* One centred column (phones and small tablets). */
.hero-copy { max-width: 860px; text-align: center; }
.hero-copy .hero-title, .hero-copy .lede { text-align: center; }
/* "Every Sunday" carries the gradient and the swash, so its box is width: fit-content.
   text-align cannot move a shrink-to-fit block; without these margins it sits hard against
   the left edge while the two lines above it are centred. */
.hero-copy .hero-title .ht-when { margin-left: auto; margin-right: auto; }
.hero-copy .lede { max-width: 640px; margin-left: auto; margin-right: auto; }
.hero-copy .app-launch { margin-left: auto; margin-right: auto; text-align: left; }
.hero-copy .ai-prompt { max-width: 560px; margin-left: auto; margin-right: auto; justify-content: center; }
.hero-copy .hero-howto { margin-left: auto; margin-right: auto; }
.hero-copy .hero-register { margin-left: auto; margin-right: auto; }
#heroLive, #heroLive .hl-rot, #heroLive .hl-rot-line { text-align: center; }
#heroLive .hl-row { justify-content: center; }

@media (max-width: 640px) {
  .hero-map { max-width: 100% !important; }
  .hero-copy { text-align: center; }
}

/* ---------- From 1240px: the promise on the left, the way in on the right ----------
   The breakpoint is set by the headline, not by taste. Its three lines are nowrap, and the
   longest, "Free AI & Web Development", measures 706px at the 3.6rem cap. The left column has
   to beat that or the headline runs under the card. At 1240px the band is 1200 wide, which
   leaves 1200 - 64 gap - 400 card = 736px on the left: 30px of headroom. Narrower than that
   and the one centred column below is the right answer. If you change the gap, the card width
   or the headline size, re-check that sum. */
@media (min-width: 1240px) {
  .hero-copy {
    display: grid;
    /* Right column widened 400px -> 520px (founder 2026-10-18: "make the container bigger"). The left
       column still gets the rest, ~640px of a 1200px band, which the headline clears easily. */
    grid-template-columns: minmax(0, 1fr) minmax(380px, 520px);
    column-gap: 64px;
    row-gap: 0;                 /* the children keep their own margins; see the span below */
    align-items: start;
    max-width: 1200px;
    text-align: left;
    padding-top: 8px;
  }
  /* Everything except the card runs down the left. The card sits in the right column and
     spans the rows, so a tall card never stretches the gap between the headline and the lede.
     row-gap is 0, so the empty rows the span creates cost nothing. */
  .hero-copy > * { grid-column: 1; }
  .hero-copy > .app-launch { grid-column: 2; grid-row: 1 / span 40; align-self: start; }
  /* A grid item stretches to its column by default, which would make the How it works button
     736px wide. These two keep their own width. */
  .hero-copy > .hero-howto, .hero-copy > .hero-register { justify-self: start; }

  .hero-copy .hero-title { text-align: left; margin: 0 0 20px; }
  .hero-copy .hero-title .ht-when { margin-left: 0; margin-right: 0; }
  .hero-copy .lede { text-align: left; max-width: 34em; margin-left: 0; margin-right: 0; font-size: 1.08rem; }
  .hero-copy .ai-prompt { margin-left: 0; margin-right: 0; justify-content: flex-start; }
  .hero-copy .hero-howto { margin-left: 0; margin-right: 0; }
  .hero-copy .hero-register { margin-left: 0; margin-right: 0; }
  #heroLive, #heroLive .hl-rot, #heroLive .hl-rot-line { text-align: left; }
  #heroLive .hl-row { justify-content: flex-start; }
  #heroLive { margin-top: 18px; }

  /* The card, as a panel you act on rather than a notice you read past. Square corners stay
     (square.css). The green is the app's colour and it keeps it. */
  .hero-copy .app-launch {
    width: 100%; max-width: none; margin: 0;
    padding: 24px 26px 22px;
    border-color: rgba(34, 197, 94, .55);
    background: linear-gradient(180deg, rgba(34, 197, 94, .13), rgba(34, 197, 94, .05) 62%, transparent);
    box-shadow: 0 24px 48px -30px rgba(34, 197, 94, .7);
  }
  .hero-copy .app-launch-tag { font-size: .68rem; letter-spacing: .18em; }
  .hero-copy .app-launch h2 { margin: 12px 0 6px; font-size: 1.34rem; line-height: 1.2; }
  .hero-copy .app-launch p { margin: 0 0 18px; font-size: .95rem; }

  /* Two buttons of equal weight, side by side and full width, so the panel ends on one
     clear line of action instead of two ragged pills. */
  .hero-copy .app-launch-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .hero-copy .app-launch-btns a {
    width: 100%; justify-content: center; text-align: center;
    padding: 13px 12px; font-size: .86rem; letter-spacing: .04em;
  }

  /* The desktop links read as a footnote to the panel, under a hairline in the same green. */
  .hero-copy .app-launch-desk {
    margin-top: 18px; padding-top: 14px;
    border-top: 1px solid rgba(34, 197, 94, .24);
    gap: 8px 16px;
  }
}


/* ===== Phones: keep the whole hero copy on one centred axis =====
   Founder 2026-10-18: "This section is not responsive ... Resize everything".
   hero-clean.css wraps .ai-prompt at <=640px and gives the typed line `padding-left: 36px`, which lines it
   up under the label on a LEFT-aligned hero - but this layout is centred, so the typed phrase ("write my CV")
   landed off to one side underneath centred text and read as broken. Centre it with the label instead.
   This file loads after hero-clean.css (index.html), so these win without !important. */
@media (max-width: 640px) {
  .hero-copy .ai-prompt { justify-content: center; column-gap: 8px; row-gap: 4px; }
  .hero-copy .ai-prompt-line { padding-left: 0; justify-content: center; }
  /* The label carries its own ":" (hero-clean.css), so the two rows read as one sentence. */
  .hero-copy .ai-prompt-label { white-space: normal; text-align: center; }
}

/* ===== The app box sits BELOW the words (founder 2026-10-18, option C) =====
   The map stays first - that is the layout the founder asked for ("Move this down ... so the map or globe
   full the hero section"), so it is untouched. The problem was the green "Student app is live" box sitting
   between the map and the headline, which pushed "Free AI & Web Development Training for Everyone" far down
   the page on a phone. Moving it to the end of .hero-copy gives: map -> headline -> lede -> typed line ->
   How it works -> app box.
   Scoped below 1240px on purpose: at >=1240px hero-stack.css puts .app-launch in its own grid column, and
   that two-column arrangement must keep working. Its 30px gap moves from the bottom to the top now that it
   follows the text instead of leading it. */
@media (max-width: 1239px) {
  .hero-copy { display: flex; flex-direction: column; }
  .hero-copy > .app-launch { order: 1; margin: 30px auto 0; }
}

/* ===== The typed line gets room for the whole phrase =====
   Founder 2026-10-18: "Make sure it's responsive on mobile, desktop, laptop etc".
   ai-fx.css sets `.ai-prompt { width: min(100%, 400px) }` so that typing can never reflow the
   hero. On the old narrow hero column that was right. In this layout the text column is 736px,
   and 400px left only 166px for the typed phrase, so "summarize a 40-page report" was being cut
   to "summarize a 40-page" on every screen from a tablet up. A max-width cannot fix that: an
   explicit `width` beats it. The width stays fixed, so typing still never reflows anything.
   560px is the max-width this file already sets above, so the two agree and the longest phrase
   in the rotation, "plan my small business budget", fits with room to spare.
   Phones are untouched: there the line wraps to its own row and already has the space. */
@media (min-width: 641px) {
  .hero-copy .ai-prompt { width: min(100%, 560px); }
}

/* ===== The app announcement: one row each, and it moves (founder 2026-10-18) =====
   "Put this in one row each" - both lines already fitted on one row at every width, but only just:
   measured at 768px the paragraph needed 288px inside a 288px box (0px spare) and at 360px it had 1px
   spare, so any difference in font rendering or a zoom step wrapped them. nowrap now guarantees it, and
   below 980px the type comes down a touch and the box's side padding narrows so nowrap cannot overflow.
   Also "animate that section": the pieces rise in one after another on load, a slow sheen crosses the
   panel, and the tag's dot breathes. All of it is transform/opacity only and all of it stops for
   prefers-reduced-motion. .app-launch had no ::before/::after of its own, so the sheen is free to use one. */
.hero-copy .app-launch h2,
.hero-copy .app-launch p { white-space: nowrap; }
/* A bigger panel (founder 2026-10-18: "make the container bigger ... no overflow text").
   hero-clean.css gave it `width: fit-content` above 641px, so it shrank to its content - 400px sitting in a
   1200px column, and 316px inside a 342px phone column. It now fills its column up to 560px, which also buys
   the room to put the type back to full size with nowrap still safe. Only the narrowest phones step down:
   at 360px the sentence needs ~288px and the inner width is 284px, so there the padding and type ease off. */
.hero-copy .app-launch { width: 100%; }
@media (min-width: 641px) { .hero-copy .app-launch { width: 100%; max-width: 560px; } }
/* Narrow phones: let the two nowrap lines SCALE instead of pinning a size. At 320px the sentence needed
   ~276px inside a 246px panel and was being clipped; tying it to vw keeps it inside at any width, and the
   clamp ceiling means nothing shrinks on a normal phone. */
@media (max-width: 400px) {
  .hero-copy .app-launch { padding-left: 12px; padding-right: 12px; }
  .hero-copy .app-launch h2 { font-size: clamp(.92rem, 4.3vw, 1.08rem); }
  .hero-copy .app-launch p { font-size: clamp(.68rem, 3.5vw, .86rem); }
}

@media (prefers-reduced-motion: no-preference) {
  .hero-copy .app-launch { position: relative; overflow: hidden; }
  /* the sheen */
  .hero-copy .app-launch::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -40%; width: 40%; pointer-events: none;
    background: linear-gradient(100deg, transparent, rgba(134, 239, 172, .20) 45%, rgba(255, 255, 255, .28) 55%, transparent);
    animation: al-sheen 7s ease-in-out 1.6s infinite;
  }
  @keyframes al-sheen { 0% { left: -40%; } 55%, 100% { left: 115%; } }
  /* the pieces arrive one after another */
  .hero-copy .app-launch > * { animation: al-rise .55s cubic-bezier(.2, .8, .2, 1) both; }
  .hero-copy .app-launch > :nth-child(1) { animation-delay: .05s; }
  .hero-copy .app-launch > :nth-child(2) { animation-delay: .14s; }
  .hero-copy .app-launch > :nth-child(3) { animation-delay: .23s; }
  .hero-copy .app-launch > :nth-child(4) { animation-delay: .32s; }
  .hero-copy .app-launch > :nth-child(5) { animation-delay: .41s; }
  @keyframes al-rise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
  /* the "New" dot breathes */
  .hero-copy .app-launch-tag::before { animation: al-dot 2.4s ease-in-out infinite; }
  @keyframes al-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .55; transform: scale(.82); } }
}
