/* Overrides carried across verbatim from the live index.php / gallery.php
   <style> blocks, plus the layout the live site expressed through W3.CSS grid
   columns and inline styles. Nothing here is a new design decision. */

/* --- Roboto, self-hosted ------------------------------------------------
   The live site fetches this from fonts.googleapis.com on every page: a
   render-blocking request to a third party, on the critical path, for the
   only typeface the site uses. Same font, same weights, same files Google
   serves - one variable file per subset, so 300, 400 and 700 all come out of
   one 43 KB download instead of three. Roboto is Apache 2.0; self-hosting is
   what the licence is for. Not a type decision: identical bytes. */
@font-face {
  font-family:'Roboto'; font-style:normal; font-weight:100 900;
  font-display:swap;
  src:url('roboto-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
    U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,
    U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family:'Roboto'; font-style:normal; font-weight:100 900;
  font-display:swap;
  src:url('roboto-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,
    U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

.b { font-weight: 700; }
.sb { font-weight: 400; }
.i { font-style: italic; }
html, body { font-family: "Roboto", Verdana, sans-serif; margin: 0; }

/* index.php and gallery.php both try to override .w3-light-grey to #eaeaea,
   but the rule immediately above ends '}!important;' - a stray token after
   the closing brace. That is a CSS parse error and the override is discarded,
   so the live site actually renders W3.CSS's own #f1f1f1. Measured in a
   browser, not assumed. Replicating what is: no override. */

.jaa-visually-hidden {
  position:absolute; width:1px; height:1px; margin:-1px;
  padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* --- the two nested fixed viewports index.php uses --------------------- */
.fixviewport { position:fixed; width:100%; height:100%; top:0; left:0; }
.jaa-content { padding-top:2.5em; }
.jaa-scroll  { height:100%; overflow:auto; }

/* --- menu bar: live height 2.5em, white bottom border ------------------ */
.jaa-bar { height:2.5em; background:#f1f1f1; position:relative; z-index:5; }
.jaa-masthead { display:block; height:100%; }
.jaa-masthead img { height:100%; width:100%; object-fit:contain; object-position:left; display:block; }
.jaa-navrow { width:100%; letter-spacing:1.2px; }
.jaa-navlink { text-decoration:none; color:inherit; }
.jaa-burger { background:none; border:0; font:inherit; cursor:pointer; padding:0;
              line-height:1; }
#siteNav { position:relative; z-index:5; }

/* --- stage (galleries + pre-design) ------------------------------------
   Live site: position:fixed, full viewport, padding-top 5.5em /
   padding-bottom 6.1em, inside l2 | l8 | l2 gutter columns.             */
.jaa-stage { position:fixed; inset:0; padding:5.5em 16.6667% 6.1em; }
@media (max-width:992px) { .jaa-stage { padding-left:8.3333%; padding-right:8.3333%; } }
@media (max-width:600px)  { .jaa-stage { padding-left:0; padding-right:0; } }

.jaa-slides { position:relative; width:100%; height:100%; outline:none; }
.mySlides { display:none; position:absolute; inset:0; }
.mySlides.is-active { display:block; }
.mySlides picture, .mySlides img {
  display:block; width:100%; height:100%;
  object-fit:contain;            /* live site: background-size:contain */
  object-position:center;
}

/* --- intro ------------------------------------------------------------- */
.jaa-intro { position:relative; width:100%; height:100%; }
.jaa-intro .mySlides { opacity:0; transition:opacity .8s ease; }
.jaa-intro .mySlides.is-visible { opacity:1; }
.jaa-introlink { position:absolute; inset:0; display:block; z-index:2; }

/* The pause/play control. WCAG 2.2.2 - see site.js for why hover-pause was
   never a mechanism.

   TWO INLINE SVGs, not characters, since 2026-09-10. Johnny reported the
   play state as "the icon with white triangle": U+25B6 BLACK RIGHT-POINTING
   TRIANGLE carries an emoji presentation, so a platform whose fallback
   reaches its colour emoji font draws a dark rounded tile with a white
   triangle in it instead of a glyph in currentColor. U+275A, the pause bar,
   has no emoji presentation, which is exactly why only the play state went
   wrong. Neither Chrome nor headless Chromium on this Windows machine
   reproduces it, so the emoji font on the device Johnny looked at is the
   unverified half - but a drawn shape has no font fallback to lose, so the
   fix holds whichever way that went. It also gives exact control of size,
   which a font does not.

   The two glyphs share one 14x14 box, which is the ink box the old U+275A
   pair measured in Chromium (14.2 x 14.1, bars 5.3 wide with a 3.4 gap).
   The pause is therefore unchanged in size and shape; only its colour moved.
   The triangle is 13 wide by the same 14 tall, centred in that box. Not the
   ink area - a triangle of equal area to two bars is half again as wide and
   reads as an arrow, not a play control - and not the full 14 either, which
   read a touch larger than the bars because the triangle is one unbroken
   mass where the bars have a gap through them. 13 was chosen off an A/B of
   14/13/12 rendered at 8x against the bars, not off the viewBox.

   Colour #808080 (CSS `grey`), by Johnny's instruction on 2026-09-10 -
   "change the colour of the pause button from black to grey". He was
   reading #595959 as black. 3.50:1 against the #f1f1f1 page ground, which
   clears WCAG 1.4.11's 3:1 for non-text contrast with margin. (#8B8B8B is
   3.02:1 and was rejected for having none. The old #595959 is 6.20:1 on
   #f1f1f1 - the 7.0:1 recorded here on 2026-09-09 was measured against
   white, which is not the surface it sits on.)

   WHAT #808080 DOES NOT FIX, measured 2026-09-10 and pre-existing: the
   comment here used to claim the corner is always the #f1f1f1 ground
   because object-fit:contain letterboxes or pillarboxes every slide. That
   is true of the literal corner and false of the glyph, which sits 8px in.
   Whenever a slide's aspect ratio lands near the stage's, the bars are
   narrower than that inset and the photograph runs under the control. At
   1024x768 that is 41 of the 65 intro slides; at 1280x800, 4; at 768x1024,
   12. Sampling every pixel under the glyph on those 41 slides, 28 of them
   already contain sub-3:1 pixels against #595959, worst case 1.00:1.
   #808080 measures 23 of 41, same worst case - so the new grey is not what
   breaks it and is fractionally better, because that corner is more often
   dark than light. No flat colour can pass over arbitrary photography; that
   needs a scrim, a plate or a shadow, which is a visual decision and is
   held for Johnny rather than defaulted.

   z-index 4 puts it above .jaa-introlink (2) and both splashes (3), which is
   the whole game: the introlink is inset:0 over the entire viewport, so a
   control below it would send every press to projects-completed/. It is a
   SIBLING of the anchor, not inside it - interactive content inside <a> is
   invalid HTML - so a click on the button never bubbles into the link.

   44x44 is the hit target and is now the button's whole box: flex centring
   replaced the 12px/14px padding, which sized the box off the glyph and made
   the target depend on the font. */
.jaa-pause {
  position:absolute; right:.5em; bottom:.5em; z-index:4;
  border:0; background:transparent; cursor:pointer; padding:0;
  display:flex; align-items:center; justify-content:center;
  font-size:20px; line-height:1; color:#808080;
  width:44px; height:44px;
}
.jaa-pause svg { display:block; width:.7em; height:.7em; fill:currentColor; }
/* aria-pressed is the single source of truth for the state - the same
   attribute the screen reader reads. site.js sets it and nothing else. */
.jaa-pause[aria-pressed="true"]  .jaa-glyph-pause,
.jaa-pause[aria-pressed="false"] .jaa-glyph-play { display:none; }
.jaa-pause:hover, .jaa-pause:focus-visible { color:#0C7F41; }

/* The two splash acts. Solid ground so the photograph behind them is not
   half-visible during the ceremony - on the live site the slides are
   display:none until the ceremony ends, which came to the same thing. */
.jaa-splash {
  position:absolute; inset:0; z-index:3; background:#f1f1f1;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  opacity:0; transition:opacity 1s ease;
}
.jaa-splash.is-visible { opacity:1; }
/* The logo is a link, so the 30% width lives on the ANCHOR and the image
   fills it. Put the width on the image instead and the anchor stretches to
   the full flex line, which puts a viewport-wide focus ring around a logo
   that occupies a third of it. */
.jaa-splashlink { display:block; width:30%; }
.jaa-splashlink img { display:block; width:100%; height:auto; }
.jaa-splash2 { padding:0 16.6667%; }
.jaa-splash2 p { width:100%; margin:.8em 0; }
/* height:auto is load-bearing, not tidiness. The badges are 1000x339 and
   carry width/height attributes, which the HTML spec maps to PRESENTATIONAL
   HINTS - author CSS beats them. Setting width here overrode the width hint
   and left the height hint standing at an absolute 339px, so the box was
   60% wide by 339px tall: 1.70:1 at 1440, 0.91:1 at 768 - squashed toward
   square, and past it. Johnny reported it as "forced square" and he was
   describing the arithmetic. .jaa-splashlink img above never had the bug
   because it sets height:auto, which is the only difference between them.
   The 600px variant below overrides width only, so it inherits this. */
.jaa-splash2 img { width:60%; height:auto; }
@media (max-width:600px) {
  .jaa-splashlink { width:50%; }
  .jaa-splash2 img { width:90%; }
  .jaa-splash2 { padding:0 4%; }
}

/* --- arrows: live site 3.5em wide, white, hover green, hidden on small --- */
.jaa-arrow {
  position:fixed; top:0; height:100%; width:3.5em;
  border:0; background:transparent; cursor:pointer;
  font-size:36px; line-height:1; color:#fff;
  opacity:.75; padding:0 .2em; z-index:3;
}
.jaa-arrow:hover, .jaa-arrow:focus-visible { color:#0C7F41; opacity:1; }
.jaa-prev { left:16.6667%; text-align:left; }
.jaa-next { right:16.6667%; text-align:right; }
@media (max-width:992px) { .jaa-prev { left:8.3333%; } .jaa-next { right:8.3333%; } }

/* --- chrome: caption bar, back link, info toggle ----------------------- */
.jaa-chrome { position:fixed; left:16.6667%; right:16.6667%; top:0; z-index:4; }
.jaa-chrome > div { margin:0; }
@media (max-width:992px) { .jaa-chrome { left:8.3333%; right:8.3333%; } }
@media (max-width:600px)  { .jaa-chrome { left:0; right:0; } }
.jaa-caption { font-size:15px; }

/* Live site used .w3-text-grey #757575 on #f1f1f1 = 4.07:1, which fails
   WCAG AA for normal text. #595959 is the same neutral at 7.0:1 - the
   minimum change that clears AA. Ratified by Johnny 2026-09-06. */
.jaa-link { color:#595959; text-decoration:none; }
.jaa-link:hover, .jaa-link:focus-visible { color:#0C7F41; }   /* see the green block below */
.jaa-linkbutton { background:none; border:0; font:inherit; cursor:pointer; padding:0;
                  min-height:24px; display:inline-flex; align-items:center; }
.jaa-sc { font-variant:small-caps; vertical-align:6%; }

/* --- the site green ----------------------------------------------------
   #4CAF50 is W3.CSS's stock green; it arrived with the framework and was
   never chosen by anyone. At 12px normal on the #f1f1f1 menu bar it is
   2.46:1 and was the site's last WCAG AA colour-contrast failure.
   #0C8041 - the green in sqweb.png, which Johnny ratified for the logo -
   lifted that node to 4.448:1: a large improvement, and 0.05 short of the
   4.5:1 AA threshold that 12px normal-weight text has to clear. The
   threshold is a property of the size, not of the green.
   #0C7F41 is that green with one hex digit changed (80 -> 7F). It measures
   4.504:1 on #f1f1f1 and clears AA. The shift is dE 0.67 - imperceptible;
   for scale, #4CAF50 -> #0C8041 was dE 22. Ratified by Johnny 2026-09-07
   after the 4.448:1 measurement was reported.
   The same value is used on the gallery arrows, so the site carries one
   green rather than two.
   Overrides W3.CSS here rather than editing vendor/w3.css, so the vendored
   file stays a byte-for-byte copy of the upstream release. !important is
   required because the W3.CSS rules it overrides carry it. */
.w3-text-green, .w3-hover-text-green:hover { color:#0C7F41 !important; }
.w3-green, .w3-hover-green:hover { background-color:#0C7F41 !important; }
.w3-border-green, .w3-hover-border-green:hover { border-color:#0C7F41 !important; }


#mySidenav .jaa-info { max-height:60vh; overflow-y:auto; overflow-x:hidden; }
.jaa-info-extra { margin-top:1em; }

/* --- filmstrip: live site 6em tall, 8em wide tiles, 1px margin --------- */
.jaa-strip {
  position:fixed; bottom:0; left:16.6667%; right:16.6667%; height:6em;
  white-space:nowrap; overflow-x:auto; overflow-y:hidden; z-index:4;
}
@media (max-width:992px) { .jaa-strip { left:8.3333%; right:8.3333%; } }
@media (max-width:600px)  { .jaa-strip { left:0; right:0; } }
.demo {
  display:inline-block; margin:1px; padding:0; border:0;
  height:6em; width:8em; cursor:pointer; background:#ddd; opacity:.75;
}
.demo:hover, .demo:focus-visible { opacity:1; }
.demo.is-active { opacity:1; }
.demo img { width:100%; height:100%; object-fit:cover; display:block; }

/* --- project grids ------------------------------------------------------
   Live tile: 10em tall, 1px light-grey border, cover crop at 50% 60%,
   4 across on large, 3 on medium, 2 on small. Caption is a white bar
   revealed on hover; :focus-within is added so a keyboard user can read
   the titles too, which on the live site they cannot. */
.jaa-tile { display:block; position:relative; text-decoration:none; float:left;
            width:25%; height:10em; border:1px solid #f1f1f1; }
@media (max-width:992px) { .jaa-tile { width:33.33%; } }
@media (max-width:600px)  { .jaa-tile { width:50%; } }
.jaa-tile figure { margin:0; height:100%; }
.jaa-tile img { width:100%; height:100%; object-fit:cover; object-position:50% 60%; display:block; }
.jaa-tile figcaption {
  position:absolute; top:50%; left:0; width:100%; transform:translateY(-50%);
  background:#fff; color:#000; text-align:center; padding:4px 0;
  letter-spacing:-0.5pt; display:none;
}
.jaa-tile:hover figcaption, .jaa-tile:focus-visible figcaption,
.jaa-tile:focus-within figcaption { display:block; }

@media (prefers-reduced-motion: reduce) {
  .jaa-intro .mySlides, .jaa-splash { transition:none; }
}
