/* ==========================================================================
   Student Art Society — one artist's page
   Path: MITD/v5/sites/sas-home/assets/sas/css/artist.css

   Loaded only on /artist.php, through $C['extra_css'], AFTER sas.css. It uses
   sas.css's tokens, buttons, chips and footer and adds the four bands that
   exist nowhere else: the artwork head with its profile card, the works grid,
   the story panel and the row of other artists.

   ITS OWN SHEET rather than more lines on sas.css. sas.css is on the front
   door, and a page family that only needs its components on one URL should not
   make every other page download them -- the note at the top of sas.css says
   this is how a page family gets its parts. It also means a mistake in here
   cannot reach the homepage.

   TWO RULES THIS FILE KEEPS THROUGHOUT, both of them scars:

   1. NO 'ch' MAX-WIDTHS ON AN ELEMENT WITH NO FONT-SIZE OF ITS OWN. 'ch'
      resolves against the element's own computed font-size, so a cap on a
      wrapper that merely contains a 48px headline measures in the body's 16px
      characters -- which is how a 30ch cap became a 275px box around a line
      that needed 430 and broke a word across two lines. Measures are set on
      the element that carries the type, or in px/%.

   2. EVERY GRID TRACK IS minmax(0, 1fr), NEVER 1fr. A bare 1fr track has an
      auto minimum, so a long word or a wide image refuses to shrink and pushes
      the row off the side of the screen with overflow-x: hidden quietly hiding
      the evidence.
   ========================================================================== */

/* ==========================================================================
   The head — artwork, name, quote, tags, and the profile card over it
   ========================================================================== */

/* Full bleed. .band's side padding is removed here and re-applied inside the
   stage, so the artwork reaches both edges of the window while the words it
   sits under stay on the same gutter as every other band on the site. */
.band--ahead { padding: 0; }

.ahead__stage {
  position: relative;
  display: grid;
  align-items: end;
  min-height: clamp(340px, 46vw, 600px);
  padding: clamp(40px, 6vw, 90px) var(--gut) 0;
  overflow: hidden;
}
.ahead__art {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 32%;
}
/* No artwork yet: the designed empty state, not a hole. Same gradient family
   as the homepage hero's .is-empty so the two read as one site. */
.ahead__stage.is-empty {
  background:
    radial-gradient(120% 90% at 18% 10%, rgba(138, 77, 255, .32), transparent 62%),
    radial-gradient(110% 80% at 86% 24%, rgba(255, 61, 158, .26), transparent 60%),
    linear-gradient(180deg, var(--panel-2), var(--void));
}
/* Darkest at the bottom, where the type is. A single flat scrim over the whole
   picture would cost the artwork more than it gives the text. */
.ahead__veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(5, 6, 14, .52) 0%, rgba(5, 6, 14, .16) 34%,
                            rgba(5, 6, 14, .72) 78%, var(--void) 100%);
}

.ahead__copy {
  position: relative; z-index: 2;
  min-width: 0;
  max-width: 100%;
  /* Room underneath for the profile card to lie across the bottom edge without
     covering the tags. Tied to the same clamp the card's negative margin uses,
     so the two move together. */
  padding-bottom: clamp(56px, 9vw, 140px);
}

.ahead__eyebrow {
  color: var(--cyan);
  font-size: 12.5px; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase;
  text-shadow: var(--lift);
}

.ahead__name {
  margin-top: 10px;
  font-size: clamp(38px, 7.2vw, 92px);
  font-weight: 800;
  font-stretch: 112%;
  line-height: .96;
  letter-spacing: -.02em;
  text-shadow: var(--lift);
  /* The measure lives HERE, on the element that carries the type, and in
     characters of ITS OWN size -- see rule 1 at the top of this file. */
  max-width: 18ch;
  overflow-wrap: break-word;
  hyphens: auto;
}

/* The quote used to sit here, under the name over the artwork. It is in the
   profile card now -- see the note in bands/artist-head.php. The rules are
   gone rather than left unused: a selector nothing emits is a thing the next
   person has to check before changing. */

.ahead__tags {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: clamp(16px, 2vw, 24px);
}
.ahead__tags li {
  padding: 6px 13px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgba(5, 6, 14, .52);
  backdrop-filter: blur(6px);
  color: var(--ice);
  font-size: 12.5px; font-weight: 600;
  letter-spacing: .04em;
}

/* --------------------------------------------------------------------------
   The profile card
   -------------------------------------------------------------------------- */
.acard2 {
  position: relative; z-index: 3;
  margin: clamp(-120px, -8vw, -40px) var(--gut) 0;
  padding: clamp(20px, 2.4vw, 34px);
  border: 1px solid var(--hairline);
  border-radius: 18px;
  background: rgba(10, 13, 26, .86);
  backdrop-filter: blur(18px);
  box-shadow: 0 24px 70px rgba(0, 0, 0, .55);
  display: grid;
  gap: clamp(14px, 1.8vw, 22px);
  /* Wide screens: who-they-are on the left, bio in the middle, actions at the
     end. One column until there is room for three, because the bio is the only
     part with a measure worth protecting. */
}
@media (min-width: 980px) {
  .acard2 {
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr) minmax(0, 230px);
    align-items: start;
    gap: clamp(20px, 2.6vw, 44px);
  }
  /* PLACED EXPLICITLY, not left to auto-flow. The middle and the quote are
     both optional, and with auto-placement an artist with no mediums put
     "Get in touch" in the middle column with an empty track beside it. Naming
     the column each part belongs to means a missing part leaves a gap where it
     would have been rather than shuffling everything along. */
  /* ROW as well as column, and the row is the half that matters. With only
     the columns set, auto-placement put the full-width bio in row 2 and then
     had nowhere in row 2 for the actions -- so "Get in touch" landed in a row
     THREE, half a card below the bio, with a band of nothing above it.
     Pinning all three to row 1 also lets the markup keep its reading order,
     bio before buttons, which is the order that makes sense when this stacks
     into one column on a phone. */
  .acard2__quote { grid-column: 1; grid-row: 1; }
  .meds         { grid-column: 2; grid-row: 1; }
  .acard2__acts { grid-column: 3; grid-row: 1; }

  /* CENTRED AGAINST EACH OTHER, not hung from the top of the card.
     With everything aligned to the start, a one-line quote sat at the very
     top of its column while the icons -- which are two lines, a glyph and a
     word -- and the button beside it filled more height. The row looked
     stepped rather than level.
     Centring each cell in the row means whichever is tallest sets the height
     and the others sit in the middle of it, so a short quote, a row of icons
     and a single button all read as one line of card. The bio is not included:
     it is a block of prose on its own row and belongs at the start of it. */
  .acard2__quote,
  .meds,
  .acard2__acts { align-self: center; }

  /* The bio takes the full width underneath.
     grid-COLUMN: 1 / -1 is safe here because the columns above are explicit --
     -1 resolves against the last line of the declared template. That is the
     opposite of grid-ROW: 1 / -1 with implicit rows, which silently resolves
     back to line 1 and does nothing; this file's own works grid was bitten by
     exactly that. With no bio there is simply no second row, so no gap. */
  .acard2__bio { grid-column: 1 / -1; grid-row: 2; }
}

/* Selectors nothing emits are deleted rather than left behind. Gone so far:
   .acard2__name (the duplicate name), .acard2__says (a wrapper the quote once
   needed), and .acard2__face / __who / __id / __role / __where -- the portrait,
   role and location, removed from the record. A dead rule is one more thing to
   check before changing anything near it. */

.acard2__quote {
  position: relative;
  margin: 0;
  padding-left: clamp(18px, 1.8vw, 26px);
  font-size: clamp(15px, 1.25vw, 18.5px);
  font-style: italic;
  line-height: 1.5;
  color: var(--ice);
}
/* Drawn, not typed. As CSS content it is not in the accessibility tree, so a
   screen reader hears the sentence rather than "left double quotation mark"
   in front of it -- and <blockquote> has already said this is a quotation. */
.acard2__quote::before {
  content: "\201C";
  position: absolute; left: -.04em; top: -.3em;
  font-size: clamp(34px, 3.4vw, 46px);
  line-height: 1;
  color: var(--magenta);
  opacity: .9;
}
.acard2__quote p { margin: 0; }
/* The bio sits on its own row under everything, so it gets a rule above it:
   the quote is the artist's voice and the bio is the museum's, and without a
   break they read as one run of text that changes person halfway through. */
.acard2__bio {
  padding-top: clamp(12px, 1.4vw, 18px);
  border-top: 1px solid var(--hairline-lo);
}

/* --------------------------------------------------------------------------
   What they work in

   Icons with the word underneath, from the catalogue in inc/sas/mediums.php.
   Wrapped rather than scrolled: there are at most a handful per artist, and a
   row that needs dragging to read is worse than one that takes two lines.
   -------------------------------------------------------------------------- */
.meds {
  display: flex; flex-wrap: wrap;
  gap: clamp(12px, 1.6vw, 22px);
  min-width: 0;
}
.med {
  display: grid; justify-items: center; gap: 7px;
  width: clamp(64px, 7vw, 86px);
  text-align: center;
}
.med__i {
  width: clamp(26px, 2.4vw, 32px); height: clamp(26px, 2.4vw, 32px);
  color: var(--cyan);
  stroke-width: 1.4;
}
.med__label {
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  color: var(--ash);
  overflow-wrap: break-word; hyphens: auto;
}

.acard2__bio { min-width: 0; }
.acard2__bio p { margin: 0; color: var(--ash); font-size: 14.5px; line-height: 1.65; }
.acard2__bio p + p { margin-top: .7em; }

.acard2__acts { display: flex; flex-wrap: wrap; gap: 10px; align-content: start; min-width: 0; }
.acard2__acts .btn { padding: 10px 16px; font-size: 13px; }

/* ==========================================================================
   Featured works
   ========================================================================== */
.band--works { padding-top: clamp(38px, 5vw, 72px); }

.wintro { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px; min-width: 0; }
.wintro__title {
  font-size: clamp(24px, 3.1vw, 42px); font-weight: 800; font-stretch: 110%;
  line-height: 1.02; letter-spacing: -.015em;
  min-width: 0; overflow-wrap: break-word;
}
/* NO margin between the spans. They are inline and the newline between them in
   the markup already renders as one word space -- adding .32em on top of it is
   what made "Featured works" read as "Featured  works". The hero's version of
   this rule is fine because .hero__line is display: block, so there is no
   markup space to double. Same below for the story and more-artists titles. */
.wintro__title .is-accent { color: var(--cyan); }
.wintro__lede { color: var(--ash); font-size: 13.5px; min-width: 0; }

/* THE RAIL. .scroller__track in sas.css does the scrolling, the snapping and
   the hidden scrollbar; this only sets how wide a card is and how much room
   the band leaves around it.

   Rows were the first shape and they stopped working the moment an artist had
   more than four pieces: a second row pushed the story and everything under it
   a screen further down, so a prolific artist buried their own page. A rail is
   one card tall whatever the count. */
.wrail { position: relative; margin-top: clamp(12px, 1.5vw, 18px); }
.wrail__nav { position: absolute; inset: 0; pointer-events: none; }
.wrail__nav .scroller__btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  pointer-events: auto;
}

.works { align-items: stretch; }
/* flex-basis, not a grid track: the card has to keep its width while the track
   scrolls, and a grid column would divide the visible width instead. */
.works > .work { flex: 0 0 clamp(210px, 23vw, 290px); }

/* --------------------------------------------------------------------------
   Filter by medium
   -------------------------------------------------------------------------- */
.wfilter {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: clamp(14px, 1.8vw, 22px);
}
.wfilter[hidden] { display: none; }
.wfilter__b {
  padding: 7px 15px;
  border: 1px solid var(--hairline); border-radius: 999px;
  background: rgba(10, 13, 26, .6);
  color: var(--ash);
  font: inherit; font-size: 12.5px; font-weight: 600; letter-spacing: .04em;
  cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
.wfilter__b:hover { border-color: var(--cyan); color: var(--ice); }
/* The chosen one is solid rather than outlined, so "which filter is on" reads
   at a glance instead of being a border weight away from the others. */
.wfilter__b.is-on {
  background-image: linear-gradient(100deg, var(--violet), var(--magenta));
  border-color: transparent; color: #0B0413;
}

.work {
  min-width: 0;
  border: 1px solid var(--hairline-lo);
  border-radius: 14px;
  background: var(--panel);
  overflow: hidden;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.work:hover { border-color: var(--hairline); box-shadow: 0 0 26px rgba(47, 228, 255, .14); }
.work__fig { margin: 0; display: block; }
.work__media { display: block; }
.work__media img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.work.is-empty .work__media {
  display: block;
  aspect-ratio: 4 / 5;
  background:
    radial-gradient(110% 80% at 24% 18%, rgba(138, 77, 255, .34), transparent 60%),
    linear-gradient(160deg, var(--panel-2), var(--panel));
}
.work__cap {
  display: block;
  padding: 13px clamp(12px, 1.2vw, 16px) clamp(14px, 1.4vw, 18px);
}
.work__title {
  display: block;
  font-size: 14.5px; font-weight: 700; line-height: 1.3;
  overflow-wrap: break-word;
}
.work__meta {
  display: block; margin-top: 5px;
  color: var(--ash); font-size: 12.5px;
  overflow-wrap: break-word;
}
.work__dot { margin: 0 .45em; color: var(--ash-dim); }

/* ==========================================================================
   Artist story
   ========================================================================== */
.band--story { padding-top: clamp(38px, 5vw, 72px); }

.story {
  display: grid;
  gap: clamp(18px, 2.6vw, 42px);
  align-items: start;
  padding: clamp(20px, 2.8vw, 40px);
  border: 1px solid var(--hairline-lo);
  border-radius: 18px;
  background:
    radial-gradient(90% 120% at 100% 0%, rgba(138, 77, 255, .14), transparent 58%),
    var(--panel);
}
@media (min-width: 880px) {
  /* A 70 / 30 SHELL.

     7fr and 3fr rather than the percentages themselves, because fr units are
     shares of what is left AFTER the gap is taken out. Written as 70% / 30%
     the two columns plus the gap come to more than the panel and the second
     one gets pushed out of it.

     The history is worth keeping, because this panel has now been wrong in
     three different directions. It began as 1.6fr / 0.4fr with the paragraphs
     capped at a 68-character measure, which on a wide screen meant a 1347px
     column holding 624px of words -- 723px of empty panel on one side and the
     picture squeezed to 337px on the other. Sized tracks fixed the hole and
     left a wide gap between the two halves. Centring the pair closed the gap
     and shoved the heading 327px in from the edge while every other section
     on the page starts at the 56px gutter.

     This is the version Rei asked for: the words take their seventy, the
     picture takes its thirty and fills it, and there is no leftover anywhere
     to decide what to do with. The reading measure is gone on purpose -- see
     the note on the paragraphs below. */
  .story {
    grid-template-columns: 7fr 3fr;
    gap: clamp(24px, 2.6vw, 48px);
  }
}

/* NO PICTURE, NO SECOND COLUMN. A half-width measure with nothing beside it
   reads as an image that failed to load, which is precisely the impression a
   deliberately text-only story must not give. */
.story.is-wide { grid-template-columns: minmax(0, 1fr); }

.story__words { min-width: 0; }
.story__title {
  font-size: clamp(24px, 3.1vw, 42px); font-weight: 800; font-stretch: 110%;
  line-height: 1.02; letter-spacing: -.015em;
  overflow-wrap: break-word;
}
.story__title .is-accent { color: var(--cyan); }

.story__body { margin-top: clamp(14px, 1.8vw, 22px); }
.story__body p {
  margin: 0;
  /* On the paragraph, which has its own font-size, so the measure is in
     characters of the size actually being read.
     78, matching the one-column case below: the two were 68 and 78 for no
     reason either could have given, and the narrower one was half of why the
     words looked like they stopped early. */
  max-width: 78ch;
  color: var(--ice);
  font-size: clamp(14.5px, 1.1vw, 16.5px);
  line-height: 1.75;
}
.story__body p + p { margin-top: 1em; }
/* The full measure when the panel is a single column -- 68ch is a comfortable
   line, and a wide panel with the text hugging the left third is not. */
.story.is-wide .story__body p { max-width: 78ch; }

/* Flush with the panel's right edge, and no wider than a picture wants to be.
   The track takes the leftover width so the two halves sit at the panel's two
   edges; the image inside it stops at its own maximum rather than growing to
   fill a track that is only there to push it over.

   Written as `.story > .story__art` on purpose. There is an overflow guard
   further down this file -- `.ahead__copy > *, .acard2 > *, .story > *` --
   which sets max-width: 100% on every direct child of this panel. A bare
   .story__art ties with it on specificity and loses on order, so the cap was
   computed as 100% and the picture came out 901px wide with the rule plainly
   sitting there in the stylesheet. The child combinator takes it to two
   classes and settles it. */
.story > .story__art {
  /* Stacked, below the two-column breakpoint: centred and capped, because a
     portrait picture stretched to the full width of a phone is taller than
     the screen. The side rule is added back at 880 and up. */
  min-width: 0;
  width: 100%; max-width: min(100%, 420px); margin-inline: auto;
}
/* The side layout, kept RIGHT HERE rather than up in the grid's own media
   block. It lived there first and lost: that block sits earlier in the file
   than the base rule above, so at equal specificity the base won and the
   picture stayed at its stacked 420 cap on a 1920 screen. Overrides go next
   to what they override. */
@media (min-width: 880px) {
  /* THE PICTURE FILLS ITS THIRTY. The column is the size now, so the image
     has no maximum of its own left to argue with it, and nothing is cropped
     getting there -- the height still follows the picture's own shape. */
  .story > .story__art {
    justify-self: stretch; margin-inline: 0;
    max-width: none; width: 100%;
  }

  /* NO READING MEASURE IN THE TWO-COLUMN PANEL.

     A cap here is what put the hole in this layout twice over, and a 70%
     column whose words stop two thirds of the way across is the exact thing
     this version exists to remove.

     It does mean long lines on a wide monitor -- about 137 characters at
     1920, against the 65 to 80 that reads most comfortably. That is a real
     trade and a deliberate one, and this is the single dial if it ever wants
     tempering: put a max-width back on this rule and the leftover space
     comes back with it. */
  .story__body p { max-width: none; }
}
.story__art img {
  display: block;
  width: 100%;
  /* THE PICTURE'S OWN SHAPE.

     This was locked to 4/5 and cropped with object-fit: cover, which is the
     right call for a photograph and the wrong one for what actually gets put
     here. A story picture is usually a made thing -- a collage, a poster, a
     title card with the artist's name across it -- and cover quietly trims
     whichever edge does not fit. Losing a corner of a photo is nothing;
     losing the lettering off somebody's own artwork is not.

     height: auto keeps whatever ratio was uploaded, so nothing is cut and
     nothing is letterboxed. The column's own maximum is what bounds it: at
     460px wide a 4:5 picture is 575 tall, which sits beside a story rather
     than towering over one.

     max-height and contain remain as a backstop for an extreme upload -- a
     1:3 strip would otherwise make a panel nobody can scroll past -- and at
     any ordinary shape neither of them does anything. */
  height: auto;
  /* A SCREENFUL, not a pixel count. The cap here was clamp(300px, 40vw, 640px)
     and at a phone width that is 300 -- which a perfectly ordinary 4:5 picture
     exceeds, so contain letterboxed it with bars down both sides. Measured
     against the viewport instead, an ordinary shape never reaches it at any
     width, and the only thing it still catches is the extreme upload it was
     written for: a long strip cannot take over the screen. */
  max-height: 70vh;
  object-fit: contain;
  border-radius: 12px;
  border: 1px solid var(--hairline-lo);
}

/* ==========================================================================
   More featured artists
   ========================================================================== */
.band--more { padding-top: clamp(38px, 5vw, 72px); padding-bottom: clamp(30px, 4.4vw, 64px); }

.mintro {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 12px 20px;
  min-width: 0;
}
.mintro__title {
  font-size: clamp(22px, 2.8vw, 36px); font-weight: 800; font-stretch: 110%;
  line-height: 1.04; letter-spacing: -.015em;
  min-width: 0; overflow-wrap: break-word;
}
.mintro__title .is-accent { color: var(--cyan); }

.mcards {
  display: grid;
  gap: var(--gap);
  margin-top: clamp(16px, 2vw, 26px);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* position: relative is what the stretched anchor below resolves against. */
.mcard {
  position: relative;
  min-width: 0;
  border: 1px solid var(--hairline-lo);
  border-radius: 14px;
  background: var(--panel);
  overflow: hidden;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.mcard:hover { border-color: var(--cyan); box-shadow: 0 0 26px rgba(47, 228, 255, .2); }
/* The focus ring belongs to the CARD, not to the invisible anchor inside it --
   an outline on a transparent box that covers the whole card is a ring in
   exactly the right place by luck, and it stops being so the moment the
   anchor's box changes. :focus-within puts it on the thing that is visibly
   being focused. */
.mcard:focus-within { outline: 2px solid var(--cyan); outline-offset: 3px; }
.mcard__go:focus-visible { outline: none; }

.mcard__media { display: block; }
.mcard__media img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.mcard.is-empty .mcard__media {
  display: block;
  aspect-ratio: 3 / 4;
  background:
    radial-gradient(110% 80% at 28% 16%, rgba(255, 61, 158, .28), transparent 60%),
    linear-gradient(160deg, var(--panel-2), var(--panel));
}
.mcard__body { display: block; padding: 12px clamp(12px, 1.2vw, 16px) clamp(14px, 1.4vw, 18px); }
.mcard__name {
  display: block;
  font-size: 14.5px; font-weight: 700; line-height: 1.3;
  overflow-wrap: break-word;
}
.mcard__medium { display: block; margin-top: 4px; color: var(--ash); font-size: 12.5px; }

/* THE WHOLE CARD IS THE HIT TARGET. An <a> and not a <button>: a button does
   not let its box stretch across an ancestor the way an anchor does, and that
   exact substitution already shipped once on Game Domain as a card that opened
   on Enter and ignored the mouse. */
.mcard__go { position: absolute; inset: 0; z-index: 2; }
/* Inert when the destination is not confirmed. .mcards is only built from
   artists whose page is switched on, so this should not fire -- it is here
   because every anchor on this site goes through sas_link_attrs() and one that
   is inert must not still swallow the clicks on the card behind it. */
.mcard__go[aria-disabled="true"] { display: none; }

/* ==========================================================================
   Narrower
   ========================================================================== */
@media (max-width: 1100px) {
  .mcards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  .mcards { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* The overlap goes. At this width the card is nearly as tall as the artwork,
     so lying it across the bottom edge covers the picture rather than framing
     it. */
  .acard2 { margin-top: clamp(-40px, -4vw, -16px); }
  .ahead__copy { padding-bottom: clamp(34px, 7vw, 64px); }
  .ahead__stage { min-height: clamp(300px, 64vw, 440px); }
}

@media (max-width: 560px) {
  /* TWO, NOT ONE, for both grids. These cards are tall portraits: one per row
     turns four works into four full screens of scrolling, and the whole point
     of a grid of four is that it can be taken in at a glance. At 390px two
     columns are about 170px each, which is still a legible picture and a
     readable title. */
  .mcards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .work__title { font-size: 13.5px; }
  .work__meta  { font-size: 12px; }
  /* The chevrons sit outside the track on a wide screen; at this width there
     is no room beside it, so they come inside and the cards narrow to suit. */
  .works > .work { flex: 0 0 clamp(170px, 46vw, 230px); }
  .mcard__name { font-size: 13.5px; }

  .acard2 { margin-top: 0; border-radius: 14px; }
  .ahead__name { max-width: 100%; }
}

/* Below this, two columns stop being a picture and start being a thumbnail. */
@media (max-width: 380px) {
  .mcards { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Scaled text
   ========================================================================== */
/* Everything above is clamped and in grid tracks with a zero minimum, so the
   page already survives a large text size. These are the belts for the two
   shapes that have bitten before: a long single word in a headline with
   nothing to break on, and a button whose label is wider than its own card. */
.ahead__name, .acard2__quote, .wintro__title, .story__title, .mintro__title,
.med__label, .work__title, .mcard__name {
  overflow-wrap: break-word;
}
.acard2__acts .btn { max-width: 100%; white-space: normal; text-align: center; }
.ahead__copy > *, .acard2 > *, .story > * { max-width: 100%; min-width: 0; }

/* ==========================================================================
   A featured work, full size

   The grid crops every card to 4:5 so a row of mixed shapes reads as a row.
   This is where the uncropped picture lives.
   ========================================================================== */

/* What the stretched button resolves against. */
.work { position: relative; }

.work__go { position: absolute; inset: 0; z-index: 2; cursor: zoom-in; }
/* The ring belongs to the CARD, not to the transparent button lying over it:
   an outline on that button lands in the right place by luck and stops doing
   so the moment its box changes. */
.work:focus-within { outline: 2px solid var(--cyan); outline-offset: 3px; }
.work__go:focus-visible { outline: none; }

/* SIZED BY THE PICTURE, not fixed. A <dialog> is fit-content by default and
   that is what is wanted here: a 640px-wide work gets a 640px panel instead of
   floating in the middle of a 1180px one. The max caps a large piece against
   the viewport; the min keeps the caption from being squeezed into a column by
   a tall narrow work. */
.artbox {
  max-width: min(94vw, 1180px);
  min-width: min(92vw, 380px);
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: var(--panel);
  color: var(--ice);
  overflow: hidden;
}
.artbox::backdrop { background: rgba(3, 4, 10, .84); backdrop-filter: blur(5px); }

/* Zero-height and sticky, FIRST in the markup, so the close button floats over
   the picture instead of being pushed below it -- see the note in the band. */
.artbox__shut { position: sticky; top: 0; height: 0; z-index: 3; }
.artbox__x {
  position: absolute; top: 12px; right: 12px;
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: rgba(5, 6, 14, .74); backdrop-filter: blur(6px);
  color: var(--ice); font-size: 23px; line-height: 1;
}
.artbox__x:hover { background: rgba(47, 228, 255, .2); border-color: var(--cyan); }

/* THE POINT OF ALL OF THIS: contain, not cover, so a wide piece is shown wide.
   Capped against the viewport height so a tall one does not run past the
   bottom of the screen with the caption unreachable below it. */
.artbox__art {
  display: block;
  width: auto; max-width: 100%;
  max-height: min(76vh, 820px);
  margin-inline: auto;
  object-fit: contain;
  background: var(--void);
}

.artbox__cap { padding: clamp(14px, 1.8vw, 22px) clamp(16px, 2vw, 26px); }
.artbox__title { font-size: clamp(16px, 1.6vw, 21px); font-weight: 800; letter-spacing: -.01em; }
.artbox__meta  { margin-top: 5px; color: var(--ash); font-size: 13px; }

@media (max-width: 560px) {
  .artbox { width: 100vw; max-width: 100vw; border-radius: 0; border: 0; }
  .artbox__art { max-height: 64vh; }
}

@media (prefers-reduced-motion: reduce) {
  .artbox::backdrop { backdrop-filter: none; }
}

/* WHOSE WORK THIS IS, under the title in the full-size view.
   Two readings, deliberately different in weight: "Original work" is quiet,
   because it is the ordinary case and does not need announcing; a piece built
   on someone else's characters carries a tinted chip, because that is the one
   a reader might want to notice.
   Only rendered when the artist answered -- see the note in the band. */
.artbox__rights {
  margin-top: 8px;
  color: var(--ash-dim); font-size: 12px; letter-spacing: .01em;
}
/* Violet, not amber. The public palette has no amber -- that token lives in
   the admin sheet and would have resolved to nothing here -- and a warning
   colour would have been the wrong call anyway: naming the work this piece
   draws on is information a reader may want, not a problem with the art. */
.artbox__rights.is-ip {
  display: inline-block; margin-top: 10px; padding: 4px 11px;
  border: 1px solid rgba(138, 77, 255, .5); border-radius: 999px;
  background: rgba(138, 77, 255, .14); color: var(--ice);
  font-size: 11.5px; font-weight: 600;
}
