/* ─── Image (library-image) ──────────────────────────────────────────
 * A single image composing the shared image engine. Theme-neutral: no
 * opinionated colours; the figure carries native border / spacing /
 * align via the block wrapper. The image fills its column; the caption
 * is a quiet, theme-inherited note. */
.gc-library-image {
    margin: 0;
}
/* Alignment is WordPress-native now (supports.align). A PLAIN image (no align class)
 * flows to the LEFT of the content column, exactly like a native no-align image: its
 * left edge sits level with the body text, not centred and not detached to the
 * viewport edge. An explicit .aligncenter is handled separately (below).
 *
 * How it stays put without detaching (the v2.3.696 trap): the FIGURE fills the content
 * column (max-width is the theme content width, --wp--style--global--content-size, and
 * margin-inline:auto centres the figure as a block, so on a full-width post wrapper it
 * lands on the text column instead of growing to the whole viewport). The shrink-wrap
 * moved OFF the figure and ONTO the media wrapper, so the picture sits at the LEFT of
 * that column-wide figure, level with the text, rather than being centred. Falls back
 * to 100% content width on classic / tokenless themes that define no content size. */
.gc-library-image:not(.alignleft):not(.alignright):not(.aligncenter):not(.alignwide):not(.alignfull) {
    max-width: var(--wp--style--global--content-size, 100%);
    margin-inline: auto;
}
/* Explicit centre choice: shrink-wrap the figure to the picture and centre it (the
 * pre-v2.3.700 default behaviour, now reserved for a deliberate .aligncenter). */
.gc-library-image.aligncenter {
    width: fit-content;
    max-width: var(--wp--style--global--content-size, 100%);
    margin-inline: auto;
}
/* Native left / right: the figure floats and text wraps beside it, the shape
 * core/image gives. Shipped UNCONDITIONALLY (not gated on a per-theme check),
 * because classic / tokenless themes provide no float for our figure class and
 * would otherwise leave a left/right image full-width. Logical floats keep it
 * RTL-clean. Capped at content width so a large image can never overflow. */
.gc-library-image.alignleft,
.gc-library-image.alignright {
    width: fit-content;
    max-width: var(--wp--style--global--content-size, 100%);
    margin-block-end: 0.5em;
}
.gc-library-image.alignleft {
    float: inline-start;
    margin-inline-end: 1.5em;
}
.gc-library-image.alignright {
    float: inline-end;
    margin-inline-start: 1.5em;
}
/* Wide / full alignment. The theme's constrained-layout rules stretch the FIGURE to
 * the wide or full width; the block's own default shrink-wrap (the fit-content media
 * wrapper) would then leave the picture at its natural size on the left of that wide
 * figure, so the media wrapper, either click anchor, and the image are all filled to
 * 100% here. The image width uses !important so it beats an authored inline width:Npx:
 * a full-width image fills the width regardless of any pixel width set on it (full and
 * wide mean "span", so the specific px width no longer applies). Aspect ratio still
 * shapes the filled box. */
.gc-library-image.alignwide .gc-library-image__media,
.gc-library-image.alignfull .gc-library-image__media,
.gc-library-image.alignwide .gc-library-image__link,
.gc-library-image.alignfull .gc-library-image__link,
.gc-library-image.alignwide .gc-lightbox-link,
.gc-library-image.alignfull .gc-lightbox-link {
    display: block;
    width: 100%;
    max-width: 100%;
}
.gc-library-image.alignwide .gc-library-image__img,
.gc-library-image.alignfull .gc-library-image__img {
    width: 100% !important;
    max-width: 100% !important;
}
.gc-library-image__img {
    display: block;
    max-width: 100%;
    height: auto;
    /* An authored Border is emitted on the <img> itself (it frames the picture,
     * not the caption). border-box keeps that border INSIDE max-width:100% so a
     * full-width bordered image can't overflow its column by the border width. */
    box-sizing: border-box;
}
/* When a NATIVE size locks the box shape (an aspect ratio, or a fixed width AND
 * height together) apply_native_dimensions adds `--cropped` and the picture defaults
 * to cover, so it crops to the box instead of distorting (an unfilled fixed box would
 * otherwise stretch the raster with object-fit:fill). A class-level default, NOT inline.
 *
 * Gated on the ABSENCE of a Media-fit class (`:not([class*="gc-of-"])`) so the two
 * NEVER compete on specificity: set a Media fit and the block carries a `.gc-of-*`
 * class, this rule stops matching, and the Media-fit rule (`.gc-of-* img`, which DOES
 * set object-fit) owns the fit; set none and this crop default applies. Mutually
 * exclusive by construction, so an author's Media-fit choice is never overridden. */
.gc-library-image:not([class*="gc-of-"]) .gc-library-image__img--cropped {
    object-fit: cover;
}
/* Inner box: wraps the picture PLUS its caption and shrink-wraps to the PICTURE, so
 * the caption caps at the image width (a long caption wraps under the picture, never
 * past it, via the width:0/min-width:100% caption rule below) and the picture+caption
 * pair left-aligns as ONE unit inside a column-filling no-align figure. It FILLS (100%)
 * instead when the picture must fill: wide / full alignment, or a Media fit (gc-of)
 * that needs a real box for object-fit. */
.gc-library-image__inner {
    width: fit-content;
    max-width: 100%;
}
.gc-library-image.alignwide .gc-library-image__inner,
.gc-library-image.alignfull .gc-library-image__inner,
.gc-library-image[class*="gc-of-"] .gc-library-image__inner {
    width: 100%;
}
/* The media wrapper shrink-wraps the image (width:fit-content) so it never
 * reserves more room than the picture. The authored Border / rounded corners
 * are emitted on the <img> ITSELF (StyleAttribute::MEDIA_FRAME_BLOCKS), not on
 * this wrapper. In the editor the wrapper also holds the Replace / Remove button
 * row, so framing it drew an oversized box with white space below the picture;
 * framing the <img> hugs the picture exactly on every size, and the caption stays
 * outside the frame. */
.gc-library-image__media {
    display: block;
    width: fit-content;
    max-width: 100%;
    /* Kill the inline baseline gap: in every on-click mode with a link
     * (lightbox / gallery / go-to-link / download) the <img> sits inside an
     * inline <a>, whose line-box leaves a strip of whitespace below the picture.
     * line-height:0 removes it so the frame's bottom sits flush with the image
     * and the caption isn't pushed away. The block <img> ignores it; the caption
     * is a figure sibling, so its own line-height is unaffected. */
    line-height: 0;
}
.gc-library-image__link {
    display: inline-block;
    line-height: 0;
}
/* "Media fit" (object-fit) on the Image block. The universal control writes a
 * gc-of-<hash> scope class onto the wrapper ONLY when the author sets a fit;
 * keyed on that (hash-independent [class*="gc-of-"]), the image fills its frame
 * so object-fit has a box to work against — pair it with an aspect ratio or a
 * minimum height. Without the control set there is no gc-of class, so the
 * image keeps its deliberate "shown whole" default (max-width:100%; height:auto).
 * width:100% here overrides the shrink-wrap above so the media fills the frame. */
/* Stretch the whole chain between the media wrapper and the <img> so the object-fit
 * box reaches the picture. BOTH anchor kinds must be covered: `.gc-library-image__link`
 * (the go-to-link / download modes) AND `.gc-lightbox-link` (the DEFAULT lightbox +
 * gallery modes, wrapped by Shared\Image). Missing the lightbox anchor left it
 * shrink-to-fit inline-block, collapsing the fit box in the most common click mode. */
.gc-library-image[class*="gc-of-"] .gc-library-image__link,
.gc-library-image[class*="gc-of-"] .gc-lightbox-link,
.gc-library-image[class*="gc-of-"] .gc-library-image__media {
    display: block;
    width: 100%;
    height: 100%;
}
.gc-library-image[class*="gc-of-"] .gc-library-image__img {
    width: 100%;
    height: 100%;
}
/* "Fill the space": the container decides the height, not the picture. The Media-fit
 * chain above already stretches media -> anchor -> img, but it stops at the media
 * wrapper: a percentage height there resolves against the FIGURE, whose height is
 * auto, so it collapsed to the picture's natural height. This opens the two links the
 * chain was missing (the figure and its shrink-wrapping inner box) so the height the
 * container handed the figure reaches the <img>.
 *
 * Percentages need a definite height to resolve against. The figure gets one from
 * being a stretched item of a flex or grid parent (a Columns column is exactly that);
 * in a plain block parent the height stays auto and this mode is a no-op rather than a
 * broken box, which is the correct failure: nothing to fill means nothing to do.
 *
 * Cropping is NOT set here. apply_native_dimensions marks the picture `--cropped` in
 * this mode, and the class-level default above crops it to cover, still gated on the
 * absence of a `gc-of-` class so an author's Media fit keeps winning. */
.gc-library-image--fill {
    /* Beat the shrink-wrap the align rules put on the figure: a filling picture spans
     * its container on BOTH axes, so a fit-content width would fight the height. */
    width: 100%;
    height: 100%;
    /* A stretched flex/grid item, so the figure actually receives a height to pass on
     * (a block-level figure in a flex column is stretched by default, but an author's
     * align choice can set align-self, and fill means fill). */
    align-self: stretch;
}
.gc-library-image--fill .gc-library-image__inner,
.gc-library-image--fill .gc-library-image__media,
.gc-library-image--fill .gc-library-image__link,
.gc-library-image--fill .gc-lightbox-link {
    display: block;
    width: 100%;
    height: 100%;
    /* Flex and grid give an item an automatic minimum size equal to its content, which
     * would put the picture's own height back into the calculation through the wrapper. */
    min-height: 0;
}
/* The picture must contribute NOTHING to the height, or it decides the box it was
 * supposed to be told about. Measured on the rendered page: with the chain at
 * height:100% but the <img> still in flow, a 267x400 file made the row 400px tall while
 * the sibling text column needed 292 — the percentage resolved to auto and the image won
 * again. Taking it out of flow is what actually inverts the direction: the SIBLING sets
 * the height, and the picture covers whatever height it is handed.
 *
 * The media wrapper becomes the containing block. Both anchor kinds sit between it and
 * the picture and are already stretched above, so the absolute box lands on the same
 * rectangle in every On-click mode. */
.gc-library-image--fill .gc-library-image__media {
    position: relative;
}
.gc-library-image--fill .gc-library-image__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}
/* A caption cannot coexist with a picture that consumes the whole box: the caption
 * would be pushed out of the figure. Give the pair a column so the note keeps its
 * place and the picture takes what is left. */
.gc-library-image--fill:has(.gc-library-image__caption) .gc-library-image__inner {
    display: flex;
    flex-direction: column;
}
.gc-library-image--fill:has(.gc-library-image__caption) .gc-library-image__media {
    flex: 1;
    min-height: 0;
}
.gc-library-image--fill .gc-library-image__caption {
    flex: 0 0 auto;
    height: auto;
}
/* The caption collapses whitespace runs in the EDITOR exactly like the rendered
 * page, so a typed run of spaces can't stagger the preview (the "Her / er / en /
 * caption" staircase). RichText sets `white-space: pre-wrap` as an INLINE style
 * on its editable, so this needs `!important` to win; harmless on the page (no
 * inline style there, and a figcaption is already white-space:normal). */
figcaption.gc-library-image__caption {
    white-space: normal !important;
    /* Do NOT let a long caption widen the fit-content inner box: width:0 makes the
     * caption contribute nothing to the box's intrinsic size (only the picture sizes
     * it), and min-width:100% then fills that picture-width box so the text wraps at
     * the image's edge instead of stretching past it. Both need `!important` because in
     * the CPT editor the caption is a RichText, and RichText sets `min-width:1px` as an
     * INLINE style (which beats any non-important rule at any specificity); without it
     * the editor caption collapses to ~1px while the page renders fine. Harmless on the
     * page (no inline style there, and a full-width caption still fills a wide box). */
    width: 0 !important;
    min-width: 100% !important;
}
.gc-library-image__caption {
    margin-top: 0.3em;
    font-size: 0.875em;
    line-height: 1.4;
    color: inherit;
    opacity: 0.7;
}
/* Gallery-mode trigger stubs: hidden lightbox group members the
 * runtime pages through. The hidden attribute already removes them
 * from layout / tab order / the a11y tree; the explicit rule guards
 * against theme resets that set display on anchors with higher
 * specificity than the UA [hidden] default. */
.gc-library-image__gallery-stub[hidden] {
    display: none;
}


/* Optional zoom mark (GC-A11Y-image-001, owner ruling 2026-08-15: a setting, never
 * a default). Sits in the corner of the picture, over the image rather than beside
 * it, so the layout does not move when an author turns it on. Its own translucent
 * plate carries it over any photograph, dark or light, without the block having to
 * know what the picture looks like. */
.gc-library-image__media { position: relative; }
.gc-library-image__zoom {
    position: absolute;
    inset-block-start: 0.5rem;
    inset-inline-end: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    border-radius: 50%;
    color: #fff;
    background: rgba( 20, 20, 22, 0.62 );
    pointer-events: none;
}
