/*
 * jimihay.com
 *
 * The appearance follows the old WordPress site — blueprint header, sketched wordmark, dark menu
 * bar, silver page, white cards with a gear datestamp — but nothing else does. The class names,
 * the structure and the rules below are this theme's own, and the only artwork carried across is
 * the branding: the wordmark, the "stay connected" script, the gears and the social icons.
 *
 * The blueprint grid and the metal gradients are drawn in CSS rather than copied as images. They
 * were tiled PNGs; as gradients they stay sharp on any display and their colours are editable here.
 * The values are sampled from the originals.
 */

:root {
    --jh-blueprint: #80a4e5;
    --jh-blueprint-rule: #5c8bd8;      /* the major grid line */
    --jh-blueprint-rule-soft: #8caeed; /* the lighter half-step */
    --jh-metal-top: #292929;
    --jh-metal-bottom: #070707;
    --jh-page: #bcbcbc;
    --jh-card: #ffffff;
    --jh-ink: #333333;
    --jh-ink-soft: #6b6b6b;
    --jh-link: #2b6cb0;
    --jh-rule: #e2e2e2;
    --jh-width: 62rem;
    --jh-sans: "Lucida Grande", "Segoe UI", ui-sans-serif, system-ui, sans-serif;
    --jh-serif: Georgia, "Times New Roman", ui-serif, serif;
}

*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--jh-page);
    color: var(--jh-ink);
    font: 12px/1.6 var(--jh-sans);
}

a { color: var(--jh-link); }

.jh-skip { position: absolute; left: -9999px; }
.jh-skip:focus {
    left: 1rem; top: 1rem; z-index: 10;
    background: #fff; padding: 0.5rem 0.75rem; border: 1px solid var(--jh-rule);
}

/* --- blueprint banner ---------------------------------------------------------------------- */

.jh-banner {
    /* Standing in for the old tiled PNG, whose tile was 34x195: on both axes a 2px major rule with
       a lighter 2px rule at the half-step, 34px apart across and 24px down. Sampled from
       bk_body.png rather than guessed.

       Four layers rather than one per axis, and the order is the point. In the original the dark
       rule always wins where two lines cross — checked both ways round: a dark vertical through a
       light horizontal stays dark, and so does a light vertical through a dark horizontal. One
       gradient per axis cannot express that, because each layer carries both its colours, so
       whichever axis is on top paints its light rule straight over the other's dark one. Splitting
       the colours out and stacking both dark rules above both light ones makes dark win everywhere.

       Earlier in the list is nearer the front. */
    background-color: var(--jh-blueprint);
    background-image:
        repeating-linear-gradient(
            to right,
            var(--jh-blueprint-rule) 0 2px,
            transparent 2px 34px
        ),
        repeating-linear-gradient(
            to bottom,
            var(--jh-blueprint-rule) 0 2px,
            transparent 2px 24px
        ),
        repeating-linear-gradient(
            to right,
            transparent 0 16px,
            var(--jh-blueprint-rule-soft) 16px 18px,
            transparent 18px 34px
        ),
        repeating-linear-gradient(
            to bottom,
            transparent 0 11px,
            var(--jh-blueprint-rule-soft) 11px 13px,
            transparent 13px 24px
        );
    border-bottom: 2px solid #fff;
}

.jh-banner__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0 0.5rem;
    max-width: var(--jh-width);
    margin: 0 auto;
    /* 17 + 97 + 19 = 133, the height of the old blueprint band, with the wordmark's own 97px in
       the middle. Sizing the band to the artwork rather than setting a min-height and letting the
       flex line grow is what puts the wordmark at 17px: `align-items: flex-end` aligns it to the
       bottom of the line, so any slack in the band pushed it down instead. */
    padding: 17px 1.25rem 19px;
    min-height: 133px;
}

.jh-wordmark { display: block; }

/* The old site's wordmark was not an <img> at all — it was painted into the header's background
   image, so its position had to be read out of that file rather than off the page: opaque pixels
   start 35px in and 17px down from the header's top-left corner, and the artwork is 363x97 drawn
   at natural size. The 17px is this block's padding-top; the 35px is below.

   Scaling it to 66px tall was the single biggest reason the header read smaller than the original. */
.jh-wordmark img {
    display: block;
    /* Natural size, but allowed to shrink: at 363px it is wider than a phone's viewport once the
       page padding is taken off, and a fixed height there overflows the page sideways. Stating the
       width and letting the height follow means max-width scales both together instead of
       squashing the artwork. */
    width: 363px;
    max-width: 100%;
    height: auto;
}

/* Sits on the wordmark's baseline rather than under it, as on the old site. */
/* 14px bold white, which is what the old #logo span was. It was set at 11px here — the third piece
   of the header to have been drawn smaller than the original, after the wordmark and the scribble.
   The shadow is not from the original; it is a legibility hedge for the white-on-blueprint, and the
   only thing in this rule that is not a match. */
.jh-tagline {
    margin: 0 0 0.35rem;
    color: #fff;
    font-weight: 700;
    font-size: 14px;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
}

.jh-connect {
    margin: 0 0 0.4rem auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    align-self: flex-start;
}
/* Natural size — the scribble is 145x42 and the old site drew it at exactly that, as the background
   of a block 42px tall. It was being drawn 30px tall here, which is 71%.

   Stated as a width with height auto rather than left to the HTML attributes, so max-width can
   scale both together if the header ever gets tight; the same treatment as the wordmark, and for
   the same reason. */
.jh-connect__label { display: block; width: 145px; max-width: 100%; height: auto; }
.jh-connect__links { display: flex; gap: 0.35rem; list-style: none; margin: 0; padding: 0; }
.jh-connect__links img { display: block; }
.jh-connect__links a:hover img { opacity: 0.82; }

/* --- menu ---------------------------------------------------------------------------------- */

/* Sampled down the nav strip of bk_body.png, which is where the old site's gradient actually lived
   — the first pass started at #292929 and had a single faint inset highlight, which is why it read
   flatter than the original. Top to bottom the strip is: 4px of near-black, a #4f4f4f highlight,
   43px of #333333 -> #070707, another #4f4f4f highlight, then black. The two highlight lines are
   most of what gives the bar its edge. */
.jh-menu {
    background: linear-gradient(to bottom, #333333, #070707);
    border-top: 4px solid #030303;
    border-bottom: 1px solid #000;
    box-shadow: inset 0 1px 0 #4f4f4f, inset 0 -1px 0 #4f4f4f;
}

.jh-menu__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    list-style: none;
    max-width: var(--jh-width);
    margin: 0 auto;
    padding: 0 1.25rem;
}

/* The dividers. Each item carries its own left rule and the bar closes with a right one, which is
   exactly how the old menu was built — so the first and last items are bounded too, rather than the
   rules only appearing between items. */
.jh-menu__inner > li:last-child { border-right: 1px solid #2f2f2f; }

.jh-menu__inner > li { position: relative; }

/* 42px tall, 14px bold, 12px of side padding and #ccc text are the old menu's own metrics. */
.jh-menu__inner > li > a {
    display: block;
    height: 42px;
    line-height: 42px;
    padding: 0 12px;
    border-left: 1px solid #2f2f2f;
    color: #ccc;
    font-weight: 700;
    font-size: 14px;
    text-decoration: none;
}
.jh-menu a:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.jh-menu a[aria-current] {
    background: rgba(255, 255, 255, 0.14);
    box-shadow: inset 0 -2px 0 var(--jh-blueprint);
}

/* One level deep, laid out inline rather than as a hover dropdown — no JavaScript, and nothing
   here is deep enough to need one. */
.jh-menu__sub { display: flex; list-style: none; margin: 0; padding: 0; }
.jh-menu__sub a { padding: 0.75rem 0.85rem; font-weight: 400; color: #bdbdbd; font-size: 11px; }

/* --- page ---------------------------------------------------------------------------------- */

.jh-page {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
    max-width: var(--jh-width);
    margin: 0 auto;
    padding: 1.75rem 1.25rem 3rem;
}

@media (min-width: 60rem) {
    .jh-page { grid-template-columns: minmax(0, 1fr) 13rem; }

    /* Pages drop the sidebar, and the content takes the width back rather than leaving a column of
       empty grey. Keyed off the aside actually being in the markup, so a template that overrides
       the block away cannot forget to also say so with a class. */
    .jh-page:not(:has(.jh-aside)) { grid-template-columns: minmax(0, 1fr); }
}

/* --- cards --------------------------------------------------------------------------------- */

.jh-card {
    position: relative;
    background: var(--jh-card);
    border-radius: 4px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
    margin-bottom: 1.5rem;
}
.jh-card:last-child { margin-bottom: 0; }

/* 40px of horizontal padding is not a taste decision: the gear badge overhangs the card by 33px
   and is 75px wide, so it reaches 42px past the card's left edge. Anything less and the artwork
   sits on top of the first line of the title. The original theme used exactly 40px for the same
   reason, with the title landing 1px clear of the gears. */
.jh-card__body { padding: 1.6rem 40px; }

/* A listing card leads with the title, so it does not need the breathing room a page's prose does.
   The gears rise to meet it — see .jh-card--dated .jh-datestamp below. */
.jh-card--dated .jh-card__body { padding-top: 0.9rem; }
.jh-card__foot {
    margin: 0;
    padding: 0.85rem 40px;
    border-top: 1px solid var(--jh-rule);
    font-weight: 700;
}
.jh-card__foot a { text-decoration: none; }
.jh-card__foot a:hover { text-decoration: underline; }

/* Scoped to .jh-prose so it actually wins. `.jh-prose h2` further down is (0,1,1) and a lone class
   is (0,1,0), so the bare `.jh-card__title` lost both its size and its `margin: 0` to the generic
   heading rule — the listing titles had been rendering at 19px with 1.8rem of space above them. */
.jh-prose .jh-card__title { margin: 0; font: 400 26px/1.2 var(--jh-serif); }
.jh-card__title a { color: var(--jh-ink); text-decoration: none; }
.jh-card__title a:hover { color: var(--jh-link); }

/* The gear datestamp hangs off the left edge of the card, as it did on the old site. The room for
   it is reserved on the column rather than the card, so a dated post and an undated page still line
   up with each other. 33px is the badge's own overhang, so the artwork stops exactly at the
   column's content edge and is never clipped. */
@media (min-width: 48rem) {
    .jh-main { padding-left: 33px; }
}

/* The three gears are different sizes and stepped diagonally, so the numbers cannot be a stacked
   column — each one is placed on its own gear's centre. Those centres were measured off the
   artwork, which is 75x110 and must not be cropped or scaled: every offset below is in its
   coordinates. Translating by -50% centres the text box on the point rather than starting it there,
   which is what keeps a two-digit day centred as well as a one-digit one. */
.jh-datestamp {
    /* One number drives the whole badge. The artwork is 75x110, so the box is sized from --gear,
       every span sits at a percentage of it, and every font size is an em against it — change
       --gear and the gears, the numbers and their spacing all scale together. That is what lets
       the badge survive on a phone instead of being swapped for a line of text. */
    --gear: 75px;

    position: absolute;
    left: -33px;
    /* Overhangs the top edge rather than sitting inside it, so the gears read as pinned to the
       card instead of floating in it.

       These offsets are in the *file's* coordinates, and the file is not tight to the artwork: of
       its 75x110 box, 4px along the top, 5px each side and 2px at the bottom are transparent, with
       the visible gears filling the 65x104 in the middle. So the numbers here always overstate the
       overhang by that margin — -20px puts the visible top edge 16px above the card, and -33px
       leaves the leftmost gear 28px out. Worth remembering before reading these as measurements of
       what you can see. */
    top: -20px;
    width: var(--gear);
    height: calc(var(--gear) * 110 / 75);
    margin: 0;
    background: url("images/date-gears.png") no-repeat 0 0;
    background-size: 100% 100%;
    color: #fff;
    /* Arial specifically: the numbers are set to fit inside gear teeth, and a wider default face
       overflows them. */
    font-family: Arial, Helvetica, sans-serif;
    /* 1em is the box's width, which is what makes the type scale with --gear. */
    font-size: var(--gear);
    line-height: 1;
}

.jh-datestamp span {
    position: absolute;
    display: block;
    transform: translate(-50%, -50%);
    white-space: nowrap;
    /* A hard offset with no blur — the original is a stamped-metal look, and any blur radius reads
       as a glow instead. */
    text-shadow: 1px 1px 0 #0a2764;
}

/* Gear centres as percentages of the box: (20.5, 20), (36.5, 57) and (52.5, 94) of 75x110.
   The year is the exception — it is set above its measured centre, at 82.45% rather than 85.455%,
   because centring the text box does not centre what you see: "'12" carries an apostrophe up at
   cap height, so the glyphs' visual mass sits lower in the box than the month's or the day's and
   the number reads as having slipped down its gear. Not a mistake to correct back to 94px. */
.jh-datestamp__month { left: 27.333%; top: 18.182%; font-size: 0.1467em; }
/* The big gear is a lighter blue than the two small ones, so its shadow is too; the dark navy used
   on the others turns into a smudge against it. */
/* `span.` is not decoration: `.jh-datestamp span` above is (0,1,1) and a lone class is (0,1,0),
   so without it the shared navy shadow wins and this rule silently does nothing. */
.jh-datestamp span.jh-datestamp__day {
    left: 48.667%; top: 51.818%;
    font-size: 0.32em; font-weight: 700;
    text-shadow: 1px 1px 0 #157ec4;
}
.jh-datestamp__year  { left: 70%;     top: 82.45%;  font-size: 0.1467em; }

/* The badge stays on a phone rather than degrading to a line of text, which is what it used to do.
   It could not stay at full size: the artwork reaches 37px past the card's left edge, the card only
   has 40px of text padding, and the 28px hanging outside needs somewhere to go — on a narrow screen
   that is more than the page's own 20px of side padding, so it would have run off the edge.

   Buying the room the way the desktop layout does — 33px of padding on the content column — costs a
   tenth of a 360px screen's reading width. Scaling the badge costs nothing instead: at 0.8 the
   visible artwork is 52px wide, hangs 16px out into padding that already exists (4px spare), and
   still stops 4px short of the text. Below this the numbers stop being legible before the space
   runs out, so 0.8 is the floor rather than a fitted value. */
@media (max-width: 47.99rem) {
    .jh-datestamp {
        --gear: 60px;
        left: -20px;
        top: -16px;
    }
}

/* --- prose --------------------------------------------------------------------------------- */

.jh-prose h1 { margin: 0 0 0.9rem; font: 400 26px/1.2 var(--jh-serif); }
.jh-prose h2 { margin: 1.8rem 0 0.6rem; font: 400 19px/1.3 var(--jh-serif); }
.jh-prose h3 { margin: 1.5rem 0 0.5rem; font: 700 13px/1.4 var(--jh-sans); text-transform: uppercase; letter-spacing: 0.04em; }
.jh-prose p, .jh-prose ul, .jh-prose ol { margin: 0 0 1.1rem; }
.jh-prose img { max-width: 100%; height: auto; }
.jh-prose figure { margin: 1.5rem 0; }
.jh-prose figcaption { color: var(--jh-ink-soft); font-size: 11px; margin-top: 0.4rem; }
.jh-prose blockquote {
    margin: 1.5rem 0;
    padding: 0.1rem 0 0.1rem 1rem;
    border-left: 3px solid var(--jh-blueprint);
    color: var(--jh-ink-soft);
}
.jh-prose table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; }
.jh-prose th, .jh-prose td { text-align: left; padding: 0.45rem 0.6rem; border-bottom: 1px solid var(--jh-rule); }
.jh-prose code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; background: #f2f4f7; padding: 0.1em 0.35em; border-radius: 2px; }

/* Structural markup an author can reach for from the editor's source view. */
.jh-prose .row { display: grid; gap: 1.5rem; margin: 1.5rem 0; }
@media (min-width: 38rem) { .jh-prose .row { grid-template-columns: 1fr 1fr; } }
.jh-prose .wide { margin-left: -1.9rem; margin-right: -1.9rem; }

.jh-byline { margin: -0.5rem 0 1.1rem; color: var(--jh-ink-soft); font-size: 11px; }

/* --- sidebar ------------------------------------------------------------------------------- */

.jh-widget { border-radius: 4px; overflow: hidden; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22); }

.jh-widget__title {
    margin: 0;
    padding: 0.5rem 0.85rem;
    background: linear-gradient(to bottom, #6f9ee0, #4a79c4);
    color: #fff;
    font: italic 700 12px/1.4 var(--jh-sans);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
}

.jh-widget__list { list-style: none; margin: 0; padding: 0.35rem 0; background: var(--jh-card); }
.jh-widget__list li { border-bottom: 1px solid var(--jh-rule); }
.jh-widget__list li:last-child { border-bottom: 0; }
.jh-widget__list a { display: block; padding: 0.5rem 0.85rem; text-decoration: none; }
.jh-widget__list a:hover { background: #f5f8fd; }

/* --- footer -------------------------------------------------------------------------------- */

.jh-footer {
    background: linear-gradient(to bottom, var(--jh-metal-top), var(--jh-metal-bottom));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
    color: #8f8f8f;
    text-align: center;
}
.jh-footer p { max-width: var(--jh-width); margin: 0 auto; padding: 1rem 1rem; font-size: 11px; }

.jh-pagination { display: flex; justify-content: space-between; font-weight: 700; }

/* --- portfolio ------------------------------------------------------------------------------ */

/* The old site laid these out with floated thumbnails and no clearing, so a tall logo trapped the
   next row and the grid broke into an L-shape. It was meant to be a grid; this is one. auto-fill
   with a minimum rather than a fixed column count, so the row reflows instead of overflowing. */
.jh-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 1rem;
    margin: 1.2rem 0 0;
    padding: 0;
    list-style: none;
}

.jh-grid a {
    display: flex;
    align-items: center;
    justify-content: center;
    /* The logos are different heights and aspect ratios — 233x180 next to 234x182 next to a tall
       one — so each tile is a fixed box and the artwork is centred inside it. Without this the
       row heights follow the tallest image and the grid looks ragged. */
    height: 100%;
    min-height: 148px;
    padding: 0.5rem;
    background: #fff;
    border: 1px solid #cfcfcf;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.jh-grid a:hover,
.jh-grid a:focus-visible {
    border-color: var(--jh-link);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.24);
}

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

.jh-lede { font-weight: 700; }

/* --- a project page ------------------------------------------------------------------------- */

.jh-visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* The banner is the title, so it leads and it is allowed to reach the full width of the card. */
.jh-hero { position: relative; margin: 0 0 1.2rem; text-align: center; }
.jh-hero img { display: block; width: 100%; max-width: 100%; height: auto; margin: 0 auto; }

/* Three of the projects put a logo over the banner's top-left corner, overhanging it slightly so it
   breaks out of the picture rather than sitting inside the frame. The old theme pinned it at a
   fixed 20px/5px because that layout was a fixed width and never moved; this one is fluid, so the
   offsets are percentages of the banner and the logo is capped rather than sized.
     - The offsets are negative on purpose: the logo hangs past the banner's top-left corner, which
       is what the old site did. The overhang lands in the card's padding — 40px horizontally, and
       about 26px on top. Both overhangs are capped so neither can reach that padding — see the
       max() below.
     - max-width 56% and max-height 90% are just above the largest of the three (Nexuiz's logo is
       55% of the banner's width, Ghetto Golf's is 88% of its height), so on a wide card every logo
       renders at the size the original showed and nothing is scaled up.
     - Below that the caps take over and the logo shrinks with the banner instead of swamping it,
       which the fixed-pixel original would have done at phone widths. */
/* `img.` on both, for the same reason as the datestamp's day: `.jh-hero img` above is (0,1,1) and
   a lone class is (0,1,0), so without it the shared `width: 100%` wins and the logo is stretched
   across the whole banner. */
.jh-hero img.jh-hero__banner { width: 100%; }

.jh-hero img.jh-hero__logo {
    position: absolute;
    /* A percentage of the banner, but never more than a fixed distance past its corner. max()
       picks the greater of two negatives, so the percentage governs at ordinary widths and the
       pixel value only takes over in the band around a ~940px viewport — where the sidebar has
       dropped, the card is at its widest, and the percentages would otherwise put the logo within
       a pixel or two of the card's padding. Percentages are against the banner: `left` resolves
       against its width, `top` against its height. */
    left: max(-5%, -30px);
    top: max(-8%, -18px);
    width: auto;
    height: auto;
    max-width: 56%;
    max-height: 90%;
    margin: 0;
}

.jh-shots__heading { margin-top: 1.8rem; }

/* A screenshot gallery is recognised by its *shape* — a list whose items are links to image files —
   rather than by a class. That is what lets an author build one entirely in the editor's UI:
   insert the images, link each to its full-size version, make it a bullet list, done. Requiring
   `class="jh-shots"` meant a trip through the source dialog, because the toolbar can produce a
   <ul> but cannot put a class on it.

   The href test, not just "a link round an image": the portfolio tiles are also linked images in a
   list, but they point at pages. Matching the file extension is the same rule the lightbox uses in
   site.js, so the two cannot disagree about what a screenshot is.

   .jh-shots is kept as an alias. Existing bodies carry it, and an author who writes it explicitly
   should still get a gallery. */
.jh-shots,
.jh-prose ul:has(> li > a:is([href$=".jpg" i], [href$=".jpeg" i], [href$=".png" i],
                             [href$=".gif" i], [href$=".webp" i], [href$=".avif" i]) > img) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 0.75rem;
    margin: 1rem 0 0;
    padding: 0;
    list-style: none;
}

/* No :has() needed on these two: a link wrapping an image, inside a list item, in prose, is the
   gallery case whichever way the list was marked up. */
.jh-shots a,
.jh-prose li > a:is([href$=".jpg" i], [href$=".jpeg" i], [href$=".png" i],
                    [href$=".gif" i], [href$=".webp" i], [href$=".avif" i]) {
    display: block;
    padding: 3px;
    background: #fff;
    border: 1px solid #b8b8b8;
    line-height: 0;
}

.jh-shots a:hover,
.jh-shots a:focus-visible,
.jh-prose li > a:is([href$=".jpg" i], [href$=".jpeg" i], [href$=".png" i],
                    [href$=".gif" i], [href$=".webp" i], [href$=".avif" i]):hover,
.jh-prose li > a:is([href$=".jpg" i], [href$=".jpeg" i], [href$=".png" i],
                    [href$=".gif" i], [href$=".webp" i], [href$=".avif" i]):focus-visible {
    border-color: var(--jh-link);
}

.jh-shots img,
.jh-prose li > a:is([href$=".jpg" i], [href$=".jpeg" i], [href$=".png" i],
                    [href$=".gif" i], [href$=".webp" i], [href$=".avif" i]) > img {
    display: block;
    width: 100%;
    height: auto;
}

/* Engine and studio logos. The old site floated these right, one on top of another. */
.jh-credits {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 0.9rem;
    margin-top: 1.8rem;
    padding-top: 1.2rem;
    border-top: 1px solid var(--jh-rule);
}

.jh-credits img { display: block; height: auto; }

/* --- demo reels ----------------------------------------------------------------------------- */

.jh-reel { margin: 0.8rem 0 2rem; }
.jh-reel video {
    display: block;
    width: 100%;
    max-width: 600px;
    height: auto;
    background: #000;
}

/* --- lightbox ------------------------------------------------------------------------------- */

/* Styled here rather than in the script so it can be restyled without touching behaviour, and so
   the whole thing stays legible as CSS. See public/site.js for why the trigger is the link shape. */
.jh-lightbox {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1.5rem;
    background: rgba(0, 0, 0, 0.82);
}

.jh-lightbox[hidden] { display: none; }

/* The page behind must not scroll while the overlay is up. */
.jh-lightbox-open, .jh-lightbox-open body { overflow: hidden; }

.jh-lightbox__figure {
    margin: 0;
    max-width: 100%;
    max-height: 100%;
    text-align: center;
}

.jh-lightbox__figure img {
    display: block;
    /* Bounded on both axes so a tall screenshot cannot push the controls off screen. */
    max-width: 100%;
    max-height: calc(100vh - 6rem);
    width: auto;
    height: auto;
    margin: 0 auto;
    background: #000;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.6);
}

.jh-lightbox__count {
    margin-top: 0.6rem;
    color: #d8d8d8;
    font: 11px/1.4 var(--jh-sans);
}

.jh-lightbox button {
    flex: none;
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 3px;
    cursor: pointer;
    font: 400 26px/1 var(--jh-sans);
    padding: 0.35rem 0.7rem;
}

.jh-lightbox button:hover,
.jh-lightbox button:focus-visible { background: rgba(255, 255, 255, 0.22); }
.jh-lightbox button[hidden] { display: none; }

.jh-lightbox__close {
    position: absolute;
    top: 1rem;
    right: 1rem;
}

@media (max-width: 32rem) {
    .jh-lightbox { padding: 0.75rem; gap: 0.25rem; }
    .jh-lightbox__figure img { max-height: calc(100vh - 8rem); }
}
