/* ==============================================================
   PORTHOLE VARIANT — loaded after styles.css, overrides only.
   Two changes from the ink page:
     1. the plate becomes a circular aperture with a hairline
        housing, and the ink filter is switched off so the
        photograph keeps its own colour;
     2. the arrival splits — name and teaching left, porthole
        right — which is what lets the aperture grow large
        enough for the colour to matter.
   ============================================================== */

/* ---------- 1. the aperture ---------- */

/* No ink treatment: no inversion, no luminance-to-alpha, no edge fade.
   A photograph is not ink and must not be processed like one. */
.frame img {
  filter: none;
  mix-blend-mode: normal;
  -webkit-mask-image: none;
  mask-image: none;
  object-fit: cover;              /* fill the circle, never letterbox */
  border-radius: 50%;
  /* An unresolved image must read as an empty window, not a broken one:
     the alt string would otherwise paint across the aperture. */
  color: transparent;
  overflow: hidden;
}

/* The housing: one hairline of the page's cyan, a soft inner shadow so the
   opening has thickness, and a drop shadow so it sits IN the water rather
   than on top of it. */
.frame {
  aspect-ratio: 1 / 1;            /* the aperture is round, so the box is square */
  border-radius: 50%;
  box-shadow:
    0 0 0 1px rgba(143, 197, 212, 0.34),
    0 18px 50px rgba(1, 8, 16, 0.6);
  /* faint fill so an aperture whose image is missing still reads as glass */
  background: radial-gradient(circle at 50% 42%, rgba(16, 60, 91, 0.5), rgba(3, 16, 26, 0.72));
  overflow: hidden;
}
.frame::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  pointer-events: none;
  box-shadow: inset 0 0 26px 6px rgba(1, 10, 20, 0.62);
}

/* ---------- 2. the split arrival ---------- */

/* The children are grid-placed rather than stacked, so the aperture gets a
   column to itself instead of competing with the type for vertical room.
   Order in the DOM is unchanged. */
.reveal-inner {
  width: min(1240px, 100%);
  display: grid;
  /* The picture column is generous only where there is width to pay for it.
     At 1.4fr on a 924px window the text column falls to 331px and a 148-word
     teaching becomes 900px tall — which is what forced the solver into its
     last lever and pushed the doors below the fold. Narrow windows get a
     balanced split; the large picture returns once the window can afford it. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  column-gap: 48px;
  align-items: center;
  text-align: left;
  justify-content: center;
}
.reveal-head {
  grid-column: 1; grid-row: 1;
  align-items: flex-start;
  /* one more line of air, so the name clears the copy above it, and the same
     indent the teaching carries so the name sits flush with the text below */
  padding-top: 84px;
  padding-left: 48px;
}
/* The direction line is a single phrase and must never break mid-phrase.
   The indented column has ~75px of slack at the sheet's own size, so it
   keeps that size and tracking — only the wrap is constrained here. */
.reveal-head .direction {
  white-space: nowrap;
}
.painting {
  grid-column: 2; grid-row: 1 / span 2;
  justify-self: center; align-self: center;
}
/* ID specificity, to outrank the short-viewport clamps in styles.css that
   were written for the old stacked layout. In the split the aperture has a
   column of its own, so it fills that column and is bounded by height
   alone — the text column, not the image, now sets the arrival's height. */
#reveal .painting,
#reveal .is-long .painting {
  /* Bounded by BOTH its column and the window. A circle takes its height
     from its width, so a column-only rule made a wide window overflow
     further, not less — the doors ended up hundreds of pixels below the
     fold. Here the aperture SPANS the head and teaching rows, so its budget
     is the window less the doors and the page chrome. */
  width: min(100%, 500px, max(200px, calc(100vh - 300px)));
  margin: 0;
}
/* Wide windows can afford the larger picture the design asks for. */
@media (min-width: 1180px) {
  .reveal-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.34fr); }
}
.teaching { grid-column: 1; grid-row: 2; margin-top: 22px; padding-left: 48px; }
.is-long .teaching { margin-top: 18px; }

/* one column always — the left half is too narrow to break in two, and when
   the solver widens the teaching to the full row it stays one column too
   (see .wide-single); parallel paragraphs were rejected. */
.body, .is-short .body, .is-long .body {
  columns: 1; max-width: none; margin: 0; text-align: left;
}
.reveal-inner.wide-single .body { columns: 1; max-width: none; margin: 0; }
/* The aperture must not collapse when the solver widens the teaching: with
   the photograph pinned to row 1 only, its column can otherwise shrink to
   the height of the name beside it. */
/* In wide-single the aperture no longer spans two rows — it sits ABOVE the
   full-width teaching, so aperture + teaching + doors are all stacked and
   its budget is much tighter than in the default layout. */
.reveal-inner.wide-single .painting { grid-row: 1; }
#reveal .reveal-inner.wide-single .painting,
#reveal .reveal-inner.wide-single.is-long .painting {
  width: min(100%, 420px, max(180px, calc(100vh - 620px)));
}

/* Door placement. Grid items with a max-width resolve to START, not centre —
   the flex parent used to centre these, so every row must say it explicitly.
   (These were lost to a line-wise edit; without them the dive button and the
   three ways out share a row in separate columns.) */
.btn-dive, .btn-absent { grid-column: 1 / -1; justify-self: center; margin-top: 26px; }
.actions, .again-row { grid-column: 1 / -1; justify-self: center; }

/* Once the teaching is widened the doors give ground too — they are the
   largest consumer after the aperture. */
.reveal-inner.wide-single .btn-dive { padding: 11px 32px; margin-top: 14px; }
.reveal-inner.wide-single .btn-dive small { font-size: 13px; }
.reveal-inner.wide-single .actions a,
.reveal-inner.wide-single .actions button { padding: 9px 16px; }
.reveal-inner.wide-single .again-row { margin-top: 6px; }
.reveal-inner.wide-single .again-row .btn-quiet { padding: 9px 18px; }

/* Laptop heights. The longest teaching (Fin Whale, 149 words) needs 791px of
   stack at the 19px type floor, so a 768px window would miss the fold by a
   couple of dozen pixels. Rather than shrink the type below what is readable,
   the head and the door rows give up the last of their air — measured to
   clear the fold at 760px without touching the teaching. */
@media (max-height: 820px) {
  .reveal-inner.wide-single.tight-head .reveal-head,
  .reveal-inner.wide-single .reveal-head { padding-top: 30px; }
  .reveal-inner.wide-single .reveal-head .rule { margin-top: 12px; }
  .reveal-inner.wide-single .teaching { margin-top: 14px; }
  .reveal-inner.wide-single .btn-dive { margin-top: 10px; padding: 10px 30px; }
  .reveal-inner.wide-single .actions { margin-top: 12px; }
  .reveal-inner.wide-single .again-row { margin-top: 4px; }
  /* Below ~740px the doors cannot clear the fold whatever is trimmed, so the
     page scrolls and the picture must NOT be sacrificed for nothing. Only in
     the band where the trim actually buys the fit does the aperture give
     ground. */
  #reveal .reveal-inner.wide-single .painting,
  #reveal .reveal-inner.wide-single.is-long .painting {
    width: min(100%, 420px, max(240px, calc(100vh - 620px)));
  }
}
@media (min-height: 740px) and (max-height: 820px) {
  #reveal .reveal-inner.wide-single .painting,
  #reveal .reveal-inner.wide-single.is-long .painting { width: 150px; }
}
/* The deep teaching gets its own way onward — the same pill as the arrival's,
   so the two levels read as one system. */
#depth .btn-dive {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; white-space: nowrap; margin: 0;
  font-size: 15px; letter-spacing: 0.2em; padding: 18px 46px; gap: 0;
}
/* "or Spin" is the quieter of the two — the same pill, less lit. */
#depth .depth-spin {
  background: rgba(143, 197, 212, 0.08);
  border-color: rgba(143, 197, 212, 0.4);
  box-shadow: none;
  padding: 18px 36px;
}
#depth .depth-spin:hover {
  background: rgba(143, 197, 212, 0.18);
  border-color: rgba(206, 238, 248, 0.85);
  box-shadow: 0 0 28px rgba(143, 197, 212, 0.22);
}

/* ---------- the depth view keeps the paintings ----------
   The arrival is photographic; the deep teaching is ink. The painting is
   borderless here exactly as on the ink build — no aperture, no ring — so
   the water runs straight through it. */
.sigil { display: none; }
.depth-port {
  display: block; width: min(420px, 76%); margin: 0 auto;
  animation: surface 3s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
.depth-port .frame {
  width: 100%; aspect-ratio: 11 / 6;
  border-radius: 0; box-shadow: none; background: none;
}
.depth-port .frame::after { content: none; }
.depth-port .frame img.ink {
  object-fit: contain; border-radius: 0;
  filter: brightness(1.05) url(#ink-to-light) brightness(0.94);
  -webkit-mask-image:
    radial-gradient(ellipse 80% 80% at 50% 50%, #000 30%, transparent 96%),
    radial-gradient(ellipse 17% 20% at 93% 88%, transparent 52%, #000 100%);
  mask-image:
    radial-gradient(ellipse 80% 80% at 50% 50%, #000 30%, transparent 96%),
    radial-gradient(ellipse 17% 20% at 93% 88%, transparent 52%, #000 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* ---------- 3. the doors, as ovals ----------
   The aperture is a circle, so the doors under it are pills rather than
   rectangles — the whole arrival then has one geometry instead of two.
   In Depth is the offer and must win: a brighter fill, a real ring of
   light around it, and its own row. The three ways out stay quiet. */
.btn-dive {
  border-radius: 999px;
  /* one line of type, so the pill is a row rather than a stack and takes
     exactly the width its words need */
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; max-width: none; white-space: nowrap;
  font-size: 15px; letter-spacing: 0.2em;
  padding: 18px 52px; gap: 0;
  background: linear-gradient(180deg, rgba(143, 197, 212, 0.3), rgba(143, 197, 212, 0.13));
  border-color: rgba(180, 222, 236, 0.82);
  box-shadow:
    0 0 0 6px rgba(143, 197, 212, 0.07),
    0 0 46px rgba(143, 197, 212, 0.24),
    inset 0 1px 0 rgba(207, 233, 242, 0.22);
}
.btn-dive:hover {
  background: linear-gradient(180deg, rgba(143, 197, 212, 0.42), rgba(143, 197, 212, 0.2));
  border-color: rgba(206, 238, 248, 1);
  box-shadow:
    0 0 0 9px rgba(143, 197, 212, 0.1),
    0 0 68px rgba(143, 197, 212, 0.34),
    inset 0 1px 0 rgba(207, 233, 242, 0.3);
}
.btn-dive small {
  color: rgba(240, 250, 253, 0.92);
  white-space: nowrap;            /* one line, at full size */
  font-size: 15px;
}

/* Another sounding / Back to the beginning — the same pill as the doors
   above, only quieter, so the foot of the arrival matches its geometry. */
.again-row { gap: 14px; margin-top: 16px; }
.again-row .btn-quiet {
  border-radius: 999px;
  padding: 12px 22px;
  background: rgba(143, 197, 212, 0.04);
  border: 1px solid rgba(143, 197, 212, 0.22);
  color: rgba(226, 236, 243, 0.6);
  transition: background 700ms ease, border-color 700ms ease, color 700ms ease;
}
.again-row .btn-quiet:hover {
  background: rgba(143, 197, 212, 0.11);
  border-color: rgba(143, 197, 212, 0.5);
  color: #eaf3f7;
}

/* ---------- 4. the naming ----------
   Binomial and epithet in white rather than cyan; the epithet reads as a
   name being spoken, so it takes single quotes. */
.binomial { color: rgba(240, 248, 251, 0.86); }
.teaching-title,
.depth-title { color: rgba(240, 248, 251, 0.9); }
.teaching-title::before,
.depth-title::before { content: '\2018'; }
.teaching-title::after,
.depth-title::after { content: '\2019'; }

/* ---------- 5. the choosing ----------
   The names ride on spokes that reach past the circle's box, so at 92vw the
   longest of them run off the page. Pulling the wheel in leaves room for the
   labels; the heading goes left-justified so it stops fighting the circle
   for the centre line, while the wheel itself stays dead centre. */
/* The wheel phase pays for its own chrome: the circle is sized off the real
   height above and below it, and the rotated name labels reach ~4% past the
   circle's box, so the box is held back to leave them room. */
body[data-phase="wheel"] .stage { padding-top: 26px; padding-bottom: 26px; }
#wheel { width: 100%; }
.wheel-wrap { align-items: stretch; gap: min(20px, 2vh); width: 100%; }
.wheel-head {
  text-align: left; max-width: 620px;
  align-self: start; margin: 0 0 0 2px;
  display: flex; flex-direction: column; align-items: flex-start;
}
/* The raise is bought by tightening the head's own internal spacing, NOT by
   a negative margin — that pushed the eyebrow up into the site header's zone,
   where its mono micro-caps read as a second line of the wordmark. The
   eyebrow is also given serif at a real size so it cannot be confused with
   the nav even when close to it. */
#wheel .eyebrow {
  font-family: var(--serif); font-size: 25px; font-weight: 300;
  letter-spacing: 0.015em; text-transform: none; color: #eaf3f7;
}
#wheel .wheel-lede { margin-top: 10px; }
/* Only the three-door state needs the wider head — see styles.css. */
[data-centre="on"] .wheel-head { max-width: 860px; }
#wheel .wheel {
  /* 43 site head + 26 stage top + ~150 head + 20 gap + 26 stage bottom.
     The centre plate sits in the heading column, so it costs nothing here. */
  width: min(78vw, 820px, calc((100vh - 268px) * 0.94));
  align-self: center;
}
/* The button adds a row to the head, so the circle gives a little more back
   on genuinely short windows rather than clipping the southern names. */
@media (max-height: 700px) {
  #wheel .wheel { width: min(78vw, 820px, calc((100vh - 250px) * 0.9)); }
  #wheel .eyebrow { font-size: 22px; }
  .wheel-lede { font-size: 17px; line-height: 1.6; }
}

/* The four Medicine Wheel colours, in compass order — the same gradient the
   hub band carries, so the button and the wheel read as one system rather
   than a decorative rainbow. */
.btn-wheelcolours {
  appearance: none; cursor: pointer; margin-top: 20px;
  padding: 13px 30px; border-radius: 999px; border: 1px solid transparent;
  background:
    linear-gradient(#061c29, #061c29) padding-box,
    linear-gradient(90deg, #cea842 0%, #9e302c 33%, #56748a 66%, #e4eef5 100%) border-box;
  border-width: 2px;
  color: #f0f8fb; font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.26em; text-transform: uppercase;
  transition: box-shadow 600ms ease, letter-spacing 600ms ease;
}
.btn-wheelcolours:hover {
  box-shadow: 0 0 30px rgba(143, 197, 212, 0.26);
  letter-spacing: 0.3em;
}

.hub-band { opacity: 0.92; }
.hub-ring { opacity: 0.8; pointer-events: none; }

/* ---------- 6. per-species framing ----------
   The site's photographs are not composed for a circular crop, so a few need
   the animal pulled back into view.

   The reduction is applied to the HOUSING, not the photo inside it: scaling
   the image alone leaves a band of glass between the photo's edge and the
   ring, which reads as a thick inner circle. Scaling the whole aperture
   keeps the photo full-bleed to its own rim — a smaller porthole, no ring.
   Magnification stays on the image, since cropping in doesn't expose glass. */
.frame:has(img[data-slug="humpback-whale"]),
.frame:has(img[data-slug="north-atlantic-right-whale"]),
.frame:has(img[data-slug="sei-whale"])   { transform: scale(0.8); }
.frame:has(img[data-slug="blue-whale"])  { transform: scale(0.85); }
.frame img[data-slug="harbor-porpoise"]  { transform: scale(1.4); }

.btn-absent { border-radius: 999px; padding: 17px 40px; }

.actions a, .actions button { border-radius: 999px; padding: 14px 20px; }

@media (max-width: 900px) {
  .reveal-inner { grid-template-columns: minmax(0, 1fr); text-align: center; }
  .reveal-head { align-items: center; }
  .painting, .teaching, .reveal-head {
    grid-column: 1; grid-row: auto;
  }
  #reveal .painting, #reveal .is-long .painting { width: min(78vw, 420px); margin: 20px auto 0; }
  .teaching { margin-top: 22px; }
  .body { text-align: left; }
}
