@charset "UTF-8";
/* ==========================================================================
   ART.CSS
   ntabibian.com  ::  THE ART LANDING PAGE  ::  v2
   --------------------------------------------------------------------------
   WRITTEN     : 2026-09-14
   REVISED     : 2026-09-14, second round, from your notes
   BELONGS TO  : Art.html   (and Artist.html loads this first, then Artist.css)
   LOADS AFTER : CSS/Negar-Default.css
   SCRIPTS     : JS/Negar-JS.js   then   JS/Art-JS.js
   --------------------------------------------------------------------------
   WHAT THIS FILE IS AND WHAT IT IS NOT

   FROM Negar-Default.css, this page uses and does not re-declare:
       the five --NColor variables          [01 COLOR]
       --NFontEN, --NFontFA, --NFontDot     [03 TYPE]
       --NGap, --NPad, --NPadX, --NEase     [02 SIZES]
       the reset, .SkipLink, the focus ring, .SrOnly, .Hidden   [04 A11Y]
       .Dot, .Green, .Yellow                [06 DOT]
       the .T language machinery            [12 LANG]
       the right-click / drag blocking      [05 PROTECT]

   EVERYTHING ELSE IS DECLARED BELOW. index.css is NOT loaded here.
   --------------------------------------------------------------------------
   THIS PAGE IS LIGHT. Ground is --NColor5, type is --NColor1. 15.96:1, AAA.

   >>> GREEN AND YELLOW CANNOT BE BODY TEXT ON THIS PAGE. <<<
   Green on whitish is 1.73:1 and yellow 1.41:1. Both fail at every size.
   They are used here only as: rules, fills behind navy text, the dot, the
   focus ring, the hamburger bars, and the single letter I in the ticker,
   which is decoration with a full text equivalent in .SrOnly beside it.
   An active filter word is navy, heavy, with a green bar under it: the
   weight carries the meaning and the colour only decorates.
   --------------------------------------------------------------------------
   HOW TO FIND THINGS IN DREAMWEAVER. Search for the tag in brackets:

       [A1 PAGE]       the ground, the wrapper, the vertical rhythm
       [A2 SIZES]      the cell size rule, the ONE set of dials for the grid
       [A3 BAR]        the slim top bar
       [A4 FILTERS]    the five category words and the two tabs
       [A5 RULE]       the hairline under the bar
       [A6 TICKER]     the I statement band
       [A7 GRID]       the mosaic itself
       [A8 SPANS]      the ten tile sizes, and the tier 1 anchoring
       [A9 CARD]       one artwork tile
       [A10 CAPTION]   the name-and-year bar, and the hover rule
       [A11 FOOT]      the copyright strip under the mosaic
       [A12 FLOAT]     the four floating buttons
       [A13 POPUP]     the statement box and the menu box
       [A14 PROTECT]   the image-protection layer
       [MODE A]        landscape, tall enough   min-height: 501px
       [MODE B]        portrait, wide enough    min-width: 501px
       [MODE C]        landscape, short         max-height: 500px
       [MODE D]        portrait, narrow         max-width: 500px
       [A15 FARSI]     Persian. The layout does NOT flip. Read this one.
       [A16 MOTION]    prefers-reduced-motion
   ========================================================================== */


/* [A1 PAGE] ================================================================
   [A1 PAGE]
   The ground and the page frame. One column, top to bottom: bar, rule,
   ticker, mosaic, copyright. No side column anywhere.
   ========================================================================= */

    body.ArtPage {
        background-color: var(--NColor5);
        color: var(--NColor1);
        font-family: var(--NFontEN);
        display: flex;
        flex-direction: column;
        min-height: 100vh;
        min-height: 100svh;

    /*  --APadX   the gutter for the BAR, the TICKER and the COPYRIGHT.
        --AEdge   the gutter for the MOSAIC only, and it is deliberately
                  much thinner. You asked for the wall to sit closer to the
                  edge of the screen than the text does, at about the width
                  of the lines between the tiles. It is the grid gap plus a
                  hair, so the outer margin reads as one more gap rather than
                  as a page margin. Change this one value to change how far
                  the art sits from the edge.                              */
        --APadX: clamp(0.75rem, 2.5vw, 2rem);
        --ARule: 1px;

    /*  The quiet size. The copyright and the float labels share it, so the
        two smallest things on the page match by construction.             */
        --ACopySize: clamp(0.62rem, 0.8vw, 0.78rem);
        }

/*  >>> THIS BLOCK IS LOAD-BEARING. DO NOT DELETE IT. <<<

    Negar-Default.css [MODE D] turns <body> into a three-column grid for
    index.html and puts padding-left, padding-right and a column-gap on the
    body itself. Right for index, wrong here: this page has no side columns,
    and that padding silently stole 25px from each edge of the mosaic on a
    phone. The symptom, so it is recognisable if it comes back: the grid had
    room for one full column and one column of ZERO width, so every two-cell
    tile rendered one cell wide.

    body.ArtPage is more specific than body, so these lines win in every mode
    and every media query regardless of source order.

    THE GENERAL LESSON for Research.html and Design.html: Negar-Default.css is
    not a neutral layer. It carries index's layout in its mode blocks. Any
    page without the left column has to opt out exactly like this.        */

    body.ArtPage {
        display: flex;
        grid-template-columns: none;
        padding-left: 0;
        padding-right: 0;
        column-gap: 0;
        gap: 0;
        }


/* [A2 SIZES] ===============================================================
   [A2 SIZES]
   THE GRID DIALS. Edit this block if the mosaic feels wrong.
   --------------------------------------------------------------------------
   WHY THE v1 GRID WAS NOT SQUARE, since you spotted it and were right.
   v1 set the column as a percentage of the WIDTH and the row as a percentage
   of the HEIGHT. Those are different numbers on every screen ever made, so a
   cell was never square and a 3x3 was a rectangle of whatever shape the
   window happened to be.

   THE FIX IS ONE IDEA: declare the cell ONCE and use it for both.

       grid-template-columns: repeat(auto-fill, var(--ACell));
       grid-auto-rows: var(--ACell);

   THE TRADE: a fixed column size means the tiles do not always reach both
   edges exactly. Whatever is left is split evenly by justify-content: center.

   YOUR SIZE RULES:  mode A never under 2in  |  modes C and D between 1.5in
   and 2.5in  |  mode B between them. In CSS 1in is exactly 96px.

   Written min(max(floor, ideal), ceiling) rather than clamp() so it cannot
   silently invert if the two ends ever cross.
   ========================================================================= */

/*  THREE VALUES, NOT ONE, AND THE SCRIPT USES ALL THREE.

    --ACellMin  your floor. Never smaller than this.
    --ACell     the ideal. What the cell wants to be.
    --ACellMax  your ceiling. Never larger than this.

    Art-JS.js [T7 PLACE] reads all three, works out how many columns of about
    the ideal size fit the width available, and then sets the cell to the size
    that makes that many columns fill the width EXACTLY. So the wall starts at
    the left gutter and ends at the right one with nothing left over, and the
    cells are still square. If the script never runs, the CSS falls back to
    fixed columns of --ACell centred in the space, which is what it did before:
    correct, just not flush.                                               */

    .ArtGrid {
        --ACellMin: 2in;
        --ACell:    12.5vw;
        --ACellMax: 2.6in;
        --AGridGap: clamp(4px, 0.6vw, 10px);
        }


/* [A3 BAR] =================================================================
   [A3 BAR]
   The slim top bar.
   --------------------------------------------------------------------------
   >>> EVERYTHING IN IT SITS ON ONE BASELINE ROW AND DOES NOT JUMP. <<<
   You saw "the Artist" and "Contact" riding above the filter words. Two
   things caused it and both are fixed here.

   1. The logo is much taller than a line of type, so align-items: center was
      centring the text group on the LOGO rather than lining the words up
      with each other.
   2. The right-hand group was wrapping to its own row at some widths.

   So: the bar is a flex row with align-items: center for the logo only, and
   the five filters, the two tabs and the language switch all live in ONE
   inner flex row, .ArtBarWords, with align-items: baseline. Baseline, not
   centre, is what makes "Paint" and "Contact" sit on the same invisible line
   however their font sizes differ. Nothing in that row can wrap above
   anything else, because it is one row.
   ========================================================================= */

    .ArtBar {
        display: flex;
        align-items: center;
        gap: clamp(0.75rem, 2vw, 2rem);
        padding: calc(var(--NGap) * 0.9) var(--APadX);
        }

/*  >>> align-items IS CENTRE, NOT BASELINE, AND THAT NEEDED ONE OTHER
    CHANGE TO WORK. <<<

    Negar-Default.css [04 A11Y] gives every a and button a min-height of 44px,
    which is the standard minimum for something you tap with a thumb. It is a
    good rule and it is why the bar's boxes are all 44px tall regardless of
    their type size. Baseline alignment then put each word wherever its own
    strut fell inside that 44px box, which is how "the Artist" and "Contact"
    ended up five pixels below the filter words.

    Centring boxes that are all exactly the same height lines the words up
    exactly, and it is also what you asked for: everything centred in the bar
    rather than sitting on a shared baseline. The 44px floor is left alone;
    it is doing its job.                                                   */

    .ArtBarWords {
        flex: 1 1 auto;
        min-width: 0;
        display: flex;
        align-items: center;
        gap: clamp(0.6rem, 1.6vw, 1.6rem);
		padding-top: 1vh;
        }

    .ArtFilters,
    .ArtTabs,
    .ArtLang {
        align-items: center;
        }

/*  Every interactive thing in the bar is the same height, so centring them
    centres the words too. 44px is Negar-Default's tap-target floor.       */

    .ArtFilterBtn,
    .ArtTab,
    .ArtLang .LangBtn {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        }

    .ArtBarWords .Spacer {
        flex: 1 1 auto;
        }

/*  THE LOGO. On a whitish ground this is "NegART Logo on Light.svg".
    The Dark version index uses would disappear here.

    >>> IT POINTS AT Art.html, NOT AT "/". <<< You asked that anywhere inside
    the art part of the site the logo brings you back to the gallery rather
    than the front door. Home is still one click away, in the menu.       */

    .ArtLogo {
        flex: 0 0 auto;
        display: block;
        line-height: 0;
        }

    .ArtLogo img {
        width: auto;
        height: clamp(1.75rem, 6.5vh, 3rem);	/* original clamp(1.75rem, 4.5vh, 3rem)      */
        }


/* [A4 FILTERS] =============================================================
   [A4 FILTERS]
   The five category words, then the two tabs, then the language switch.

   ORDER IS YOURS: Paint, Digital, Lens, Stage, All.

   THEY ARE <button> AND NOT <a> because nothing navigates: the page rewrites
   which tiles are shown, in place. aria-pressed tells assistive software
   which one is on and is also what the styling hangs off, so what is seen and
   what is announced can never fall out of step.

   >>> THE ACTIVE WORD. <<< You asked for much bolder and green. Green as the
   letters themselves is 1.73:1 on this ground and unreadable, so the active
   word is navy at weight 900 with a 3px green bar under it. The weight is
   what you see from across the room; the green is what tells you which one.
   Nothing is lost and it still passes AAA. If you want to try green letters
   anyway, change the color on .ArtFilterBtn[aria-pressed="true"] and see it
   for yourself before deciding.
   ========================================================================= */

    .ArtFilters {
        display: flex;
        gap: clamp(0.6rem, 1.6vw, 1.6rem);
        flex: 0 1 auto;
        }

    .ArtFilterBtn,
    .ArtTab {
        background: none;
        border: 0;
        padding: 0 0 0.3em;
        cursor: pointer;
        font-family: inherit;
        color: var(--NColor1);
        font-size: clamp(0.85rem, 1.05vw, 1.05rem);
        line-height: 1.2;
        letter-spacing: 0.02em;
        text-decoration: none;
        white-space: nowrap;
        border-bottom: 3px solid transparent;
        opacity: 0.55;
        font-weight: 400;
        transition: opacity 0.2s var(--NEase),
                    border-color 0.2s var(--NEase);
        }

    .ArtFilterBtn[aria-pressed="true"] {
        opacity: 1;
        font-weight: 900;
        border-bottom-color: var(--NColor3);
        }

    .ArtFilterBtn:hover,
    .ArtTab:hover,
    .ArtTab:focus-visible {
        opacity: 1;
        }

    .ArtTabs {
        display: flex;
        gap: clamp(0.6rem, 1.6vw, 1.4rem);
        flex: 0 0 auto;
        }

/*  "the" set small and light, the way it is on v1's menu. A nice piece of
    your existing voice, and it costs one span.                            */

/*  THE SPACE AFTER "the" HAS TO BE A MARGIN, not a space in the text. The
    word lives in its own span so the language switch can empty it in Farsi,
    and a trailing space inside a span collapses to nothing between two inline
    boxes: it rendered as "theGallery". A margin cannot collapse.          */

    .ArtTab .the {
        font-size: 0.78em;
        opacity: 0.7;
        margin-inline-end: 0.3em;
        }

/*  >>> AND IN FARSI THE WORD GOES AWAY HERE, NOT IN THE SWITCH. <<<

    The comment above said the language switch would empty it. It does not,
    and it should not: Negar-JS [S2 LANG] treats an EMPTY data-fa as "not
    translated yet" and deliberately leaves the English standing, which is the
    right behaviour everywhere else on the site -- it is how a half-translated
    page degrades into a readable one instead of a page with holes in it.

    So the bar read "the گالری" and "the هنرمند". Persian has no definite
    article and there is nothing to translate the word INTO; it is a piece of
    English typography, not a piece of English. A style rule is the honest
    place to say that. One line, and it fixes the gallery, the statement and
    all forty-three artwork pages at once.                                 */

    body.Lang-fa .ArtTab .the { display: none; }

/*  THE LANGUAGE SWITCH.

    >>> THE WRAPPER IS .ArtLang AND NOT .LangSwitch, ON PURPOSE. <<<
    .LangSwitch in Negar-Default.css carries index's own layout for this
    control: a full --NGap of margin-top in the wide modes, and
    flex-direction: column in mode D so EN sits above فا. Both are right on
    index and wrong in a single baseline row, where they pushed the switch
    onto a second line. A different wrapper class is the clean way to opt out:
    nothing is overridden and nothing is fighting. Negar-JS.js [S2 LANG] only
    ever looks for .LangBtn, which is why that class is kept.             */

    .ArtLang {
        display: flex;
        gap: 0.35em;
        flex: 0 0 auto;
        }

    .ArtLang .LangBtn {
        background: none;
        border: 0;
        cursor: pointer;
        font-family: inherit;
        color: var(--NColor1);
        font-size: clamp(0.85rem, 1.05vw, 1.05rem);
        line-height: 1.2;
        opacity: 0.55;
        padding: 0 0 0.3em;
        border-bottom: 3px solid transparent;
        }

    .ArtLang .LangBtn[aria-pressed="true"] {
        opacity: 1;
        font-weight: 900;
        border-bottom-color: var(--NColor3);
        }

    .ArtLang .LangBtn[lang="fa"] {
        font-family: var(--NFontFA);
        }

    .ArtLang .LangDivider {
        opacity: 0.35;
        }


/* [A5 RULE] ================================================================
   [A5 RULE]
   The hairline under the bar. Dirty blue, one pixel, edge to edge rather than
   inset: a rule that stops short of the window reads as a box, one that runs
   out of it reads as a horizon.
   ========================================================================= */

    .ArtRule {
        height: var(--ARule);
        background: var(--NColor4);
        flex: 0 0 auto;
        }


/* [A6 TICKER] ==============================================================
   [A6 TICKER]
   The I statement band, between the rule and the mosaic.
   --------------------------------------------------------------------------
   THE WORD "I" IS A MARK, NOT A LETTER. You asked for it much bolder, like a
   thick green line. That is what it is: weight 900, green, and letter-spaced
   away from the sentence so it reads as a stroke rather than as the first
   letter of the first word. The left edge of the line never moves, because
   only what comes after it is typed.

   Green here is the one exception to the no-green-text rule at the top of
   this file, and it is a considered one: the whole band is aria-hidden and
   the complete list of statements sits beside it in .SrOnly, so nothing is
   carried by this letter that is not also carried in plain navy text.

   >>> IN FARSI THE I DISAPPEARS. <<< Your Persian lines already begin with
   من. Printing an English I in front of them would be wrong, so [A15 FARSI]
   hides it.

   THE HEIGHT IS FIXED AT ONE LINE. Without that, a long statement would wrap
   and push the whole mosaic down by a line and pull it back up again, once
   per statement, forever.

   The lists live in Art.html [R5 TICKER], one per category, in both
   languages. The typing itself is Art-JS.js [T1 TYPER]: no typed.js, no CDN.
   ========================================================================= */

    .ArtTicker {
        flex: 0 0 auto;
        padding: calc(var(--NGap) * 1.1) var(--APadX);
        font-size: clamp(1.15rem, 2.4vw, 2.1rem);
        line-height: 1.25;
        min-height: calc(1.25em + var(--NGap) * 2.2);
        color: var(--NColor1);
        white-space: nowrap;
        overflow: hidden;
        }

    .ArtTicker .ArtI {
        font-weight: 900;
        color: var(--NColor3);
        font-size: 1.15em;
        letter-spacing: 0.06em;
        margin-inline-end: 0.22em;
        }

    .ArtTicker .ArtType {
        white-space: pre;
        }

    .ArtTicker .ArtCaret {
        display: inline-block;
        width: 0.08em;
        height: 0.95em;
        margin-inline-start: 0.08em;
        background: var(--NColor3);
        vertical-align: -0.1em;
        animation: ArtBlink 1s steps(1) infinite;
        }

    @keyframes ArtBlink {
        50% { opacity: 0; }
        }


/* [A7 GRID] ================================================================
   [A7 GRID]
   The mosaic.

   grid-auto-flow: dense is what lets you sort by importance and still get a
   packed wall: a small tile that does not fit the current row falls BACKWARDS
   into an earlier gap a big tile left behind. Source order is your order of
   importance; the packing is the browser's problem.

   ONE CONSEQUENCE: visual order and source order are not identical, so a
   keyboard user tabbing the mosaic sometimes jumps backwards on screen. That
   is inherent to dense packing, it is not an axe violation, and the
   alternative is holes in the wall.

   THE SIDE GUTTER IS --AEdge, NOT --APadX. That is the change you asked for:
   the art sits about one grid line away from the edge of the screen while the
   bar and the copyright keep the wider text margin. See [A1 PAGE].
   ========================================================================= */

    .ArtMain {
        flex: 1 1 auto;
        }

/*  >>> THE WALL LINES UP WITH THE I. <<<
    You asked that the left edge of the mosaic sit exactly where the I of the
    I statement begins, and that the right edge match it. Both use --APadX, so
    they line up by construction rather than by eye, and they stay lined up at
    every window size because they are the same number.

    justify-content is START, not centre. With the exact-fit cell the columns
    reach both gutters anyway, so there is nothing to centre; and if the
    script ever does not run, a start-aligned wall still begins in the right
    place rather than drifting into the middle.                            */

    .ArtGrid {
        display: grid;
        grid-template-columns: repeat(auto-fill, min(max(var(--ACellMin), var(--ACell)), var(--ACellMax)));
        grid-auto-rows: min(max(var(--ACellMin), var(--ACell)), var(--ACellMax));
        grid-auto-flow: dense;
        gap: var(--AGridGap);
        justify-content: start;
        align-content: start;
        padding: var(--AGridGap) var(--APadX) calc(var(--NGap) * 2);
        }

/*  ---- THE THREE MEASURING STICKS ---------------------------------------
    Art-JS.js [T7 PLACE] needs your floor, ideal and ceiling as PIXELS, and it
    cannot simply read them: getComputedStyle hands a custom property back as
    the text you wrote, so --ACell comes out as the string "12.5vw" and
    parseFloat makes that 12.5 pixels. The wall came out as 149 columns of
    three pixels each, with no error anywhere.

    So the page measures them instead. These three are real elements, each one
    given a width from one of the three variables, and the browser resolves
    them the way it resolves any width. Reading their rendered width gives the
    real number in the real unit, whatever unit you wrote it in: in, vw, vh,
    rem, a calc, anything.

    They are absolutely positioned, so the grid does not treat them as tiles,
    and invisible and zero-height, so they cost nothing and cannot be reached
    by a screen reader or the tab key. The script creates them itself; there is
    nothing to add in the HTML.                                            */

    .ArtProbe {
        position: absolute;
        visibility: hidden;
        height: 0;
        pointer-events: none;
        }

    .ArtProbe-min { width: var(--ACellMin); }
    .ArtProbe-mid { width: var(--ACell); }
    .ArtProbe-max { width: var(--ACellMax); }

    .ArtNoScript {
        padding: calc(var(--NGap) * 3) var(--APadX);
        max-width: 46ch;
        font-size: 1rem;
        line-height: 1.6;
        }


/* [A8 SPANS] ===============================================================
   [A8 SPANS]
   The ten tile sizes, named WIDTH x HEIGHT in cells, and the tier 1 rule.
   --------------------------------------------------------------------------
   THE NAMES ARE THE POINT. v1 called these span-1 to span-8, where span-4 was
   three wide by one tall and span-8 was two wide by three tall. Nobody can
   hold that in their head, including the person who wrote it.

   >>> THESE SET grid-column-END AND grid-row-END, NEVER THE SHORTHAND. <<<
   It matters, and it cost an hour the first time.

   "grid-column: span 3" does NOT mean three columns wide. It is shorthand for
   grid-column-START: span 3 and grid-column-END: auto, which behaves like
   three wide only while nothing else sets a start. The moment something does,
   as .t1 does below, the start is replaced, the span goes with it, the end is
   still auto, and the tile silently becomes ONE column wide with its height
   untouched. Tahereh Blossoms rendered as a 1x3 strip and nothing anywhere
   reported an error. Putting the span on the END keeps the start free.
   ========================================================================= */

/*  square                                                                 */
    .s-1x1 { grid-column-end: span 1; grid-row-end: span 1; }
    .s-2x2 { grid-column-end: span 2; grid-row-end: span 2; }
    .s-3x3 { grid-column-end: span 3; grid-row-end: span 3; }

/*  horizontal                                                             */
    .s-2x1 { grid-column-end: span 2; grid-row-end: span 1; }
    .s-3x1 { grid-column-end: span 3; grid-row-end: span 1; }
    .s-3x2 { grid-column-end: span 3; grid-row-end: span 2; }
    .s-4x1 { grid-column-end: span 4; grid-row-end: span 1; }

/*  vertical                                                               */
    .s-1x2 { grid-column-end: span 1; grid-row-end: span 2; }
    .s-1x3 { grid-column-end: span 1; grid-row-end: span 3; }
    .s-2x3 { grid-column-end: span 2; grid-row-end: span 3; }


/*  ---- ORDER IS YOURS, FULL STOP ----------------------------------------
    THE TIER RULES ARE GONE, as you asked. There is no longer anything in the
    page that moves a piece because of its tier.

    WHAT USED TO BE HERE. Tier 1 pieces were pinned to column 1 so that no two
    of them could sit side by side, with a clear row forced between each. It
    worked, and it fought you: it decided where the important work went, and
    every time you reordered the spreadsheet the page rearranged itself around
    a rule you had not asked for that day.

    WHAT HAPPENS NOW. Art-JS.js [T7 PLACE] walks your list in order and puts
    each piece in the first place it fits, top left to bottom right. Big
    pieces land where you put them; small ones fall into the gaps the big ones
    leave. That is all. The wall is your spreadsheet, in order.

    TIER STILL EXISTS IN THE DATA and it still means something to you, but it
    no longer means anything to the layout. If you ever want the old behaviour
    back it is one pass in [T7 PLACE], not a rewrite.
                                                                           */

/* [A9 CARD] ================================================================
   [A9 CARD]
   One artwork tile.
   --------------------------------------------------------------------------
   THE PICTURE IS A BACKGROUND, NOT AN <img>. The single most useful thing on
   this page for protecting the work, and the same choice index's portrait
   makes. No image element under the cursor, so: no "Save image as", no drag
   to desktop, no "Copy image", and an image-only crawler looking for <img>
   finds nothing. The honest account of how far that goes is in [A14 PROTECT].

   THE ACCESSIBILITY COST IS PAID. A background carries no alt text, so the
   inner span gets role="img" and an aria-label built from the title, the
   medium and the credit. A screen reader hears exactly what an alt would have
   said. Nothing is lost.
   ========================================================================= */

    .ArtCard {
        position: relative;
        display: block;
        overflow: hidden;
        background-color: #E4EAEA;   /* what shows while the webp loads */
        text-decoration: none;
        color: inherit;
        }

    .ArtThumb {
        position: absolute;
        inset: 0;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        transition: transform 0.45s var(--NEase),
                    filter    0.35s var(--NEase),
                    opacity   0.35s var(--NEase);
        }


/* [A10 CAPTION] ============================================================
   [A10 CAPTION]
   The name-and-year bar, and the hover rule.
   --------------------------------------------------------------------------
   THE HOVER TEST IS THE INPUT, NOT THE SCREEN SIZE:

       @media (hover: hover) and (pointer: fine)

   (hover: hover) means the device can hover at all. (pointer: fine) means it
   has something precise. A tablet held in two hands matches neither. The SAME
   tablet in a keyboard case with a trackpad matches both and gets the hover
   treatment, which is correct: the question was never "is this a tablet", it
   was "is there a pointer". Width-based queries get this wrong in both
   directions.

   >>> THE RESTING DIM LIVES ONLY INSIDE THAT QUERY. <<<
   You asked for the wall to sit at about 70% and come to full strength under
   the cursor. It does, on a pointer device. On a touch screen there is no
   hover, so dimming would mean every visitor on a phone sees the whole
   gallery permanently faded, which is what v1 did to most of its visitors.
   There, the paintings are at full strength always and the first tap opens
   the work.

   THE TWO DIALS ARE --ARest AND --AGrey, right here.
   ========================================================================= */

    .ArtCap {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 2;
        display: flex;
        flex-direction: column;
        gap: 0.15em;
        padding: 0.7em 0.8em 0.65em;
        background: linear-gradient(to top,
                    rgba(9, 29, 44, 0.92) 0%,
                    rgba(9, 29, 44, 0.78) 55%,
                    rgba(9, 29, 44, 0) 100%);
        color: var(--NColor5);
        transform: translateY(101%);
        transition: transform 0.3s var(--NEase);
        pointer-events: none;
        }

/*  The title can be long and the tile can be one cell wide, so it wraps to at
    most two lines and then ends in an ellipsis rather than overflowing or
    being clipped mid-letter.                                              */

    .ArtCap b {
        font-weight: 400;
        font-size: clamp(0.62rem, 0.85vw, 0.85rem);
        line-height: 1.25;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        }

    .ArtCap i {
        font-style: normal;
        font-size: clamp(0.56rem, 0.72vw, 0.72rem);
        opacity: 0.75;
        }

/*  ALWAYS-ON CAPTION for tiles two cells wide or more: there is room, and a
    named painting is better than an anonymous one. Small tiles stay clean.
    Delete this block if you would rather the wall were completely silent.  */

    .ArtCard.s-2x2 .ArtCap,
    .ArtCard.s-3x3 .ArtCap,
    .ArtCard.s-3x2 .ArtCap,
    .ArtCard.s-2x3 .ArtCap {
        transform: translateY(0);
        }

/*  KEYBOARD PARITY: focus shows the caption on every tile, always.        */

    .ArtCard:focus-within .ArtCap {
        transform: translateY(0);
        }

/*  ---- POINTER DEVICES ONLY ---------------------------------------------- */

    @media (hover: hover) and (pointer: fine) {

        .ArtGrid {
            --ARest: 0.40;   /* your number: the wall at rest ||| Original 0.7 */
            --AGrey: 55%;    /* and a little desaturation with it ||| Originl 30% */
            }

        .ArtThumb {
            opacity: var(--ARest);
            filter: grayscale(var(--AGrey));
            }

        .ArtCard:hover .ArtThumb {
            opacity: 1;
            filter: grayscale(0%);
            transform: scale(1.03);
            }

        .ArtCard:hover .ArtCap {
            transform: translateY(0);
            }
        }


/* [A11 FOOT] ===============================================================
   [A11 FOOT]
   The copyright strip, and nothing else.
   --------------------------------------------------------------------------
   YOU ASKED FOR THE FLOATS TO BE THE FOOTER, and they are. Contact, the
   statement and the menu all live in the floating cluster now, so what is
   left down here is the copyright and the thin line above it.

   >>> THE STRIP IS INDENTED PAST THE FLOATS ON PURPOSE. <<< The floating
   cluster sits bottom left and is always visible at the foot of the page, so
   the copyright starts to the RIGHT of it and the strip is at least as tall
   as the cluster. --AFloatBoxW is that measurement, declared in [A12 FLOAT]
   and used here, so if you resize the buttons the copyright moves with them
   and can never end up underneath.

   THE WORDING AND THE AUTOMATIC YEAR RANGE are index's, unchanged, driven by
   Negar-JS.js [S4 YEAR]. 2020 is confirmed as the first year. The only
   difference from index is the colour, as you asked: navy held back rather
   than the full-strength whitish it is over there.
   ========================================================================= */

    .ArtFoot {
        flex: 0 0 auto;
        border-top: var(--ARule) solid var(--NColor4);
        padding: calc(var(--APadX) * 0.85); /*  calc(var(--NGap) * 1.1) var(--APadX) calc(var(--NGap) * 1.1)  */
        padding-inline-start: calc(var(--AFloatBoxW) + calc(var(--APadX)) * 2); /*  Original calc(var(--AFloatBoxW) + var(--APadX)            */
        min-height: var(--AFloatBoxH);
        display: flex;
        align-items: center;
        }

    .ArtCopyright {
        font-size: var(--ACopySize);
        letter-spacing: 0.06em;
        line-height: 1.75;
        color: var(--NColor1);
        opacity: 0.5;
        }

/*  ONLY THE TOP-LEVEL SPANS ARE LINES. Written as a child selector, not a
    descendant one: the first line holds the automatic year inside a nested
    span, and as a descendant rule that nested span became a block too, so the
    copyright read as four lines with a lonely © on the first.            */

    .ArtCopyright > span {
        display: block;
        }


/* [A12 FLOAT] ==============================================================
   [A12 FLOAT]
   The four floating buttons.
   --------------------------------------------------------------------------
   Bottom left, in order: the logo, the art statement, the menu.
   Bottom right, on its own: back to the top.

   They fade in once the top bar has scrolled away. Art-JS.js [T2 CHROME]
   adds .IsScrolled to <body> and removes it again at the top; every visual
   decision about what that means is here.

   THE SIZE IS THE INDEX DISC SIZE, as you asked, half again bigger than the
   first round. The logo inside sits at 85% of the circle. Each button carries
   a small label underneath at --ACopySize, the same size as the copyright, so
   the two quietest things on the page match.

   WHY THE LOGO GOES TO Art.html AND NOT TO "/". Inside the art part of the
   site the gallery is home. It behaves almost like the back-to-top arrow,
   which is what you described. The front door is still one click away, in the
   menu.

   --AFloatBoxW and --AFloatBoxH are the cluster's footprint. [A11 FOOT] uses
   them to keep the copyright clear of it. Change --AFloatD and everything
   else follows.
   ========================================================================= */

    body.ArtPage {
        --AFloatD: clamp(3.6rem, 8.25vh, 4.9rem);      /* 150% of round one */
        --AFloatGap: clamp(0.5rem, 1.2vw, 0.9rem);
        --AFloatBoxW: calc(var(--AFloatD) * 3 + var(--AFloatGap) * 2 + var(--APadX));
        --AFloatBoxH: calc(var(--AFloatD) + var(--ACopySize) * 1.6 + var(--NGap));
        }

    .ArtFloat,
    .ArtTop {
        position: fixed;
        z-index: 60;
        opacity: 0;
        visibility: hidden;
        transform: translateY(0.75rem);
        transition: opacity 0.3s var(--NEase),
                    transform 0.3s var(--NEase),
                    visibility 0s linear 0.3s;
        }

    body.IsScrolled .ArtFloat,
    body.IsScrolled .ArtTop {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        transition-delay: 0s;
        }

    .ArtFloat {
        left: var(--APadX);
        bottom: var(--APadX);
        display: flex;
        align-items: flex-start;
        gap: var(--AFloatGap);
        }

    .ArtFloatItem {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: calc(var(--NGap) * 0.3);
        background: none;
        border: 0;
        padding: 0;
        cursor: pointer;
        font-family: inherit;
        color: var(--NColor1);
        text-decoration: none;
        }

/*  ALL FOUR CIRCLES ARE NAVY, as you asked. That settles the thing the art
    disc had already forced: its drawing is made for a dark ground, so its
    button had to be navy while the others were whitish, and three identical
    pale circles plus one dark one looked like a mistake rather than a
    decision. Navy throughout also lifts the whole cluster off a whitish page
    without a shadow doing the work.

    The logo inside is therefore the DARK-ground file, "NegART Logo on
    Dark.svg", the same one index uses. The whitish one would disappear.   */

    .ArtFloatBtn {
        width: var(--AFloatD);
        height: var(--AFloatD);
        border-radius: 50%;
        border: 2px solid var(--NColor1);
        background: var(--NColor1);
        color: var(--NColor5);
        display: grid;
        place-items: center;
        overflow: hidden;
        transition: transform 0.3s var(--NEase),
                    border-color 0.3s var(--NEase),
                    box-shadow 0.3s var(--NEase);
        box-shadow: 0 2px 12px rgba(9, 29, 44, 0.22);
        }

    .ArtFloatItem:hover .ArtFloatBtn,
    .ArtFloatItem:focus-visible .ArtFloatBtn {
        transform: scale(1.06);
        border-color: var(--NColor3);
        box-shadow: 0 0 0 6px rgba(148, 208, 9, 0.12),
                    0 2px 12px rgba(9, 29, 44, 0.14);
        }

/*  The logo at 85% of the circle, as you asked. object-fit keeps it from
    stretching whatever the mark's proportions turn out to be.             */

    .ArtFloatBtn img {
        width: 75%;
        height: 75%;
        object-fit: contain;
        }

/*  THE ART DISC, and the one thing that had to change about it.

    It is index's own drawing, at index's own icon scale for that disc, 0.74,
    so the face sits inside the ring exactly the way it does over there.

    >>> BUT THAT SVG IS DRAWN FOR A NAVY GROUND. <<< Its two layers are
    whitish and yellow, which is right on index and almost invisible here: on
    the whitish button it came out as a small yellow smudge with the whole
    face missing. So this one button is filled navy rather than whitish, which
    fixes it completely and has a second benefit: the three buttons now read
    as logo, art, menu rather than as three identical circles.

    If you would rather all three were whitish, re-export the disc with a navy
    line layer and delete this block.                                      */

    .ArtFloatBtn .DiscIcon {
        width: 74%;
        height: 74%;
        object-fit: contain;
        pointer-events: none;
        }

/*  THE LABEL SITS ON A SLIM NAVY PLATE, which is what you asked for and what
    it needed: the words were floating loose on top of whatever painting
    happened to be behind them, and on a busy tile they were unreadable. A
    plate the same navy as the circle makes them part of the button and gives
    the text a ground of its own. Whitish on navy is 15.96:1.

    The plate is only as wide as its word, so the three of them read as three
    separate buttons rather than one bar.                                  */

    .ArtFloatLabel {
        font-size: var(--ACopySize);
        letter-spacing: 0.08em;
        line-height: 1.25;
        white-space: nowrap;
        background: var(--NColor1);
        color: var(--NColor5);
        padding: 0.35em 0.7em;
        opacity: 0.88;
        transition: opacity 0.2s var(--NEase);
        }

    .ArtFloatItem:hover .ArtFloatLabel,
    .ArtFloatItem:focus-visible .ArtFloatLabel,
    .ArtTop:hover .ArtFloatLabel,
    .ArtTop:focus-visible .ArtFloatLabel {
        opacity: 1;
        }

/*  ---- THE HAMBURGER, GREEN, FROM v1 -------------------------------------
    Four bars, --NColor3, and on open the outer two fade while the middle two
    cross into an X. That is v1's own mechanism and its own timing, brought
    over as you asked, with the bars set closer together than v1 had them.

    THE BARS ARE ABSOLUTELY POSITIONED inside a fixed box rather than stacked
    with margins, because the X depends on the middle two sitting in exactly
    the same place before they rotate. With margins they cross slightly off
    centre and the X looks bent.                                           */

    .ArtBurger {
        position: relative;
        width: 52%;
        height: 40%;
        }

    .ArtBurger span {
        position: absolute;
        left: 0;
        width: 100%;
        height: 15%;
        min-height: 3px;
        background: var(--NColor3);
        border-radius: 1px;
        transition: 0.45s var(--NEase);
        }

    .ArtBurger span:nth-of-type(1) { top: 0; }
    .ArtBurger span:nth-of-type(2) { top: 31%; }
    .ArtBurger span:nth-of-type(3) { top: 54%; }
    .ArtBurger span:nth-of-type(4) { top: 85%; }

    .ArtMenuToggle:checked ~ .ArtFloat .ArtBurger span:nth-of-type(1),
    .ArtMenuToggle:checked ~ .ArtFloat .ArtBurger span:nth-of-type(4) {
        opacity: 0;
        }

    .ArtMenuToggle:checked ~ .ArtFloat .ArtBurger span:nth-of-type(2) {
        top: 42%;
        transform: rotate(-45deg);
        }

    .ArtMenuToggle:checked ~ .ArtFloat .ArtBurger span:nth-of-type(3) {
        top: 42%;
        transform: rotate(45deg);
        }

/*  ---- BACK TO TOP -------------------------------------------------------
    A plain anchor to #top, so it works with JavaScript off, and
    scroll-behavior: smooth on <html> makes it glide. Bottom right, opposite
    the cluster, so a thumb reaching for one never covers the other.      */

    .ArtTop {
        right: var(--APadX);
        bottom: var(--APadX);
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: calc(var(--NGap) * 0.3);
        text-decoration: none;
        color: var(--NColor1);
        }

/*  THE ARROW IS YELLOW ON NAVY, as you asked: 11.35:1, and it is the only
    yellow on the page, which is what makes the one button that goes UP read
    differently from the three that go somewhere.                          */

    .ArtTop .ArtFloatBtn {
        font-size: calc(var(--AFloatD) * 0.44);
        line-height: 1;
        color: var(--NColor2);
        }

    html {
        scroll-behavior: smooth;
        }


/* [A13 POPUP] ==============================================================
   [A13 POPUP]
   The two floating boxes: the art statement, and the menu.
   --------------------------------------------------------------------------
   Both open UPWARD from the cluster rather than sliding in from the edge of
   the screen, which is what you asked for: a message box sitting on top of
   the page, near the button that opened it, not a panel from the right.

   They share every style below and differ only in what is inside them.

   THE MENU'S CONTENTS, as you listed them:
       Contact
       This art:      Paint, Digital, Lens, Stage, All     indented --NPadX
       Other rooms:   the Artist, the Researcher, the Designer   indented

   The indent is --NPadX exactly, so it matches the horizontal rhythm the rest
   of the site is built on.

   THE PANEL IS NAVY, and that matters: on navy the accents ARE allowed as
   text, since green on navy is 9.22:1. It is the one place on this page where
   a green word is readable, which is why the two headings use it.
   ========================================================================= */

/*  >>> THE MENU MUST FIT. IT DOES NOT SCROLL. <<<
    You asked for that directly, and it changed how the box is sized. It has
    no max-height and no overflow of its own, so it is exactly as tall as its
    contents and every line is always reachable. What makes that safe is the
    second half of the change: the rhythm inside is about 60% of what it was,
    which is what you asked for as well. Eleven lines at the old spacing did
    not fit a short laptop; at this spacing they fit a phone.

    IF YOU EVER ADD ENOUGH LINES THAT IT OVERRUNS THE SCREEN, it will run off
    the top rather than scroll. That is the trade you chose, and the fix then
    is fewer lines rather than a scrollbar.                                */

    .ArtPop {
        position: fixed;
        left: var(--APadX);
        bottom: calc(var(--APadX) + var(--AFloatBoxH) + var(--NGap) * 0.5);
        z-index: 70;
        width: min(23rem, calc(100vw - var(--APadX) * 2));
        background: var(--NColor1);
        color: var(--NColor5);
        padding: calc(var(--NGap) * 0.9) calc(var(--NGap) * 1.2) calc(var(--NGap) * 1.3);
        box-shadow: 0 8px 34px rgba(9, 29, 44, 0.32);
        opacity: 0;
        visibility: hidden;
        transform: translateY(0.6rem);
        transition: opacity 0.28s var(--NEase),
                    transform 0.28s var(--NEase),
                    visibility 0s linear 0.28s;
        }

    .ArtPop.IsOpen,
    .ArtMenuToggle:checked ~ .ArtPop-Menu {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        transition-delay: 0s;
        }

/*  A little pointer down towards the button that opened it, so the box reads
    as belonging to that button rather than floating loose.                */

    .ArtPop::after {
        content: "";
        position: absolute;
        bottom: -9px;
        width: 0;
        height: 0;
        border-left: 9px solid transparent;
        border-right: 9px solid transparent;
        border-top: 9px solid var(--NColor1);
        }

    .ArtPop-Statement::after { left: calc(var(--AFloatD) * 1.5 + var(--NGap) * 0.4); }
    .ArtPop-Menu::after      { left: calc(var(--AFloatD) * 2.5 + var(--NGap) * 0.8); }

    .ArtPopClose {
        position: absolute;
        top: calc(var(--NGap) * 0.1);
        inset-inline-end: calc(var(--NGap) * 0.5);
        background: none;
        border: 0;
        color: var(--NColor5);
        font-family: inherit;
        font-size: 1.5rem;
        line-height: 1;
        width: 1.6em;
        height: 1.6em;
        min-height: 0;
        padding: 0;
        cursor: pointer;
        opacity: 0.6;
        }

    .ArtPopClose:hover { opacity: 1; }

    .ArtPop p {
        font-size: 0.95rem;
        line-height: 1.55;
        }

    .ArtPop a {
        color: var(--NColor3);
        text-underline-offset: 0.25em;
        }

    .ArtPopMore {
        display: inline-block;
        margin-top: calc(var(--NGap) * 0.6);
        font-size: 0.95rem;
        }

/*  >>> EVERY LINE IN THE MENU IS THE SAME SIZE AND THE SAME LEADING. <<<
    The two headings were set small, uppercase and letterspaced, like labels.
    You asked for them to be the same font as everything else, and green, so
    they are: same size, same weight, same line height, green instead of
    whitish. Green on navy is 9.22:1, so inside this panel it reads properly.
    Contact is green too.

    ONE VARIABLE SETS THE WHOLE RHYTHM. --APopStep is the vertical step
    between any two lines in the box, headings included, and it is about 60%
    of what it used to be. Change that one number to open the menu up or close
    it further.                                                            */

    .ArtPop {
        --APopStep: calc(var(--NGap) * 0.34);
        --APopLine: 1.35;
        --APopSize: 1rem;
        }

/*  >>> THE 44px TAP FLOOR IS DROPPED INSIDE THIS BOX, ON PURPOSE. <<<
    Negar-Default.css [04 A11Y] gives every a and button a min-height of 44px.
    In the bar that is right. Here it made twelve lines 44px each, so the menu
    stood 600px tall and could not fit a laptop, let alone the phone you asked
    it to fit on.

    What replaces it is a row that is still comfortably tappable: the links
    stretch the full width of the panel and carry their own vertical padding,
    so the target is the whole line rather than the word. That comes out at
    about 34px, which is under the ideal 44 and well above the point where a
    thumb starts missing. It is a considered trade for a menu you asked not to
    scroll, and it is the only place on the site the floor is lifted.     */

    .ArtPop h2,
    .ArtPop .ArtPopTop,
    .ArtPopGroup a,
    .ArtPopGroup button {
        font-family: inherit;
        font-size: var(--APopSize);
        line-height: var(--APopLine);
        font-weight: 400;
        letter-spacing: 0;
        text-transform: none;
        text-decoration: none;
        background: none;
        border: 0;
        margin: 0;
        text-align: start;
        display: block;
        width: 100%;
        min-height: 0;
        padding: 0.28em 0;
        }

    .ArtPop h2 {
        color: var(--NColor3);
        margin-top: var(--APopStep);
        margin-bottom: var(--APopStep);
        }

    .ArtPop h2:first-of-type { margin-top: var(--APopStep); }

    .ArtPop .ArtPopTop {
        color: var(--NColor3);
        }

    .ArtPopGroup {
        display: flex;
        flex-direction: column;
        gap: var(--APopStep);
        padding-inline-start: var(--NPadX);
        }

    .ArtPopGroup a,
    .ArtPopGroup button {
        color: var(--NColor5);
        cursor: pointer;
        }

    .ArtPopGroup a:hover,
    .ArtPopGroup button:hover,
    .ArtPop .ArtPopTop:hover,
    .ArtPopGroup a:focus-visible,
    .ArtPopGroup button:focus-visible {
        color: var(--NColor3);
        }

    .ArtPopGroup button[aria-pressed="true"] {
        color: var(--NColor3);
        font-weight: 900;
        }

/*  The checkbox that drives the menu. Off-screen rather than display: none,
    so it stays focusable machinery; the label is what people actually use. */

/*  >>> position: FIXED, AND THAT IS THE WHOLE FIX FOR THE PAGE JUMPING. <<<

    Clicking a label moves focus to the control it points at, and a browser
    scrolls a newly focused element into view. This checkbox sat near the top
    of the document, so opening the menu from the foot of a long wall threw the
    page back to the top every time. The statement box behaved because it is a
    button, focused where it already is.

    A fixed element is always in view, so there is nothing to scroll to. It is
    one word and it is load-bearing.

    (Art-JS.js [T4 POPUPS] also focuses the first link inside the panel with
    preventScroll, which handles the second half of the same problem. Both are
    needed: that one covers the panel, this one covers the checkbox.)     */

    .ArtMenuToggle {
        position: fixed;
        top: 0;
        inset-inline-start: 0;
        opacity: 0;
        width: 1px;
        height: 1px;
        min-height: 0;
        pointer-events: none;
        }


/* [A14 PROTECT] ============================================================
   [A14 PROTECT]
   The image-protection layer, and an honest account of what it is worth.
   --------------------------------------------------------------------------
   YOU ASKED FOR MAXIMUM SECURITY. Here is every layer and how far each goes.

   1. A WATERMARK, ADDED 2026-09-14. Your logo, white, at 55% over a soft dark
      halo so it holds on a pale watercolour and on a dark canvas alike,
      bottom right, about 15% of the long side. All 43 thumbnails carry it.
      This is the only layer on the list a screenshot cannot defeat, which is
      why it is worth the small intrusion on the work.

   2. THE FILES ARE SMALL. 450px on the short side. Right in a 2in tile on a
      retina screen, far too small to print. The strongest protection here,
      because it is the only one that does not depend on goodwill.

   3. NO <img> ELEMENT ANYWHERE IN THE MOSAIC. See [A9 CARD]. Kills
      right-click save, drag to desktop, and "copy image".

   4. user-select and touch-callout, below. Kills the long-press menu on iOS
      and the selection handles that let you drag a block of the page.

   5. THE meta ROBOTS TAG in Art.html: noimageindex and max-image-preview:none.
      Google and Bing both honour it: the paintings cannot turn up in an image
      search and no thumbnail appears beside the page in results.

   6. robots.txt. Two Disallow lines were added on 2026-09-14 covering
      /Assets/Artworks thumnails 150dpi 450px+/ and /Assets/Artworks/.

   7. .htaccess hotlink protection, BLOCK 5 in your file, stops another site
      embedding your images and serving them as its own. Plus the right-click
      and drag blocking in Negar-JS.js [S5 PROTECT], site-wide.

   WHAT NONE OF IT DOES. Anyone who opens developer tools can read a file name
   and fetch it, and anyone at all can take a screenshot. No technique
   prevents either, on any website, anywhere. What these seven layers do is
   make casual copying inconvenient, make automated harvesting unlikely, keep
   the work out of image search, and ensure that whatever does get taken is a
   450px file with your mark on it.
   ========================================================================= */

    .ArtGrid,
    .ArtCard,
    .ArtThumb {
        -webkit-user-select: none;
        user-select: none;
        -webkit-touch-callout: none;
        -webkit-user-drag: none;
        }


/* ==========================================================================
   THE FOUR SCREEN MODES
   Identical to index. Each orientation is measured on the side that runs out
   first: landscape splits on HEIGHT, portrait splits on WIDTH. 500 sits in
   the empty space between the widest phone (430) and the narrowest tablet
   (600 to 744). Written max 500 / min 501 so a window of exactly 500 belongs
   to one mode only.

   >>> THE BREAKPOINT IS WRITTEN IN EIGHT PLACES NOW. <<< The table and query
   in Negar-Default.css, in index.css, here, and in Artist.css. Move one,
   move all eight.
   ========================================================================== */


/* [MODE A] ================================================================= */

    @media (orientation: landscape) and (min-height: 501px) {

        .ArtGrid {
            --ACellMin: 2in;
            --ACell:    12.5vw;
            --ACellMax: 2.6in;
            }
        }


/* [MODE B] =================================================================
   Portrait, 501px and up. You did not specify a size for B, so it sits
   between A's 2in floor and C/D's 1.5in.
       768 wide -> 169px cells -> 4 columns
       600 wide -> 154px cells -> 3 columns
   THREE COLUMNS IS THE FLOOR, so nothing may be four cells wide.
   ========================================================================= */

    @media (orientation: portrait) and (min-width: 501px) {

        .ArtGrid {
            --ACellMin: 1.6in;
            --ACell:    22vw;
            --ACellMax: 2.2in;
            }

        .s-4x1 { grid-column-end: span 3; }

    /*  The words wrap to a second row under the logo rather than squeezing.
        They still share one baseline within that row.                     */
        .ArtBarWords {
            flex-wrap: wrap;
            row-gap: calc(var(--NGap) * 0.5);
            }
        }


/* [MODE C] =================================================================
   Landscape, 500px tall or less. A phone on its side. The scarce side is
   HEIGHT, so the cell is sized from vh here rather than vw.
   NOTHING MAY BE THREE ROWS TALL: a 3-row tile would be taller than the
   window and could never be seen whole.
   ========================================================================= */

    @media (orientation: landscape) and (max-height: 500px) {

        .ArtGrid {
            --ACellMin: 1.5in;
            --ACell:    20vh;
            --ACellMax: 2.5in;
            }

        .s-3x3 { grid-row-end: span 2; }
        .s-2x3 { grid-row-end: span 2; }
        .s-1x3 { grid-row-end: span 2; }
        .s-4x1 { grid-column-end: span 3; }

        .ArtBar    { padding-block: calc(var(--NGap) * 0.5); }
        .ArtTicker {
            padding-block: calc(var(--NGap) * 0.55);
            min-height: 0;
            font-size: clamp(0.95rem, 3.2vh, 1.35rem);
            }

    /*  Always-on captions come off: at 144px a tile is small and the caption
        would cover a third of the painting.                               */
        .ArtCard.s-2x2 .ArtCap,
        .ArtCard.s-3x3 .ArtCap,
        .ArtCard.s-3x2 .ArtCap,
        .ArtCard.s-2x3 .ArtCap {
            transform: translateY(101%);
            }

        body.ArtPage {
            --AFloatD: clamp(2.6rem, 15vh, 3.4rem);
            }

    /*  THE ONE PLACE A POPUP IS ALLOWED TO SCROLL. A phone on its side is
        390px tall. The menu is about 450px. No amount of tightening fits a
        twelve-line list into a screen shorter than the list, so here, and
        only here, the box is capped and scrolls. Everywhere else it is
        exactly as tall as its contents, as you asked.                     */
        .ArtPop {
            max-height: calc(100vh - var(--AFloatBoxH) - var(--APadX) * 2.5);
            overflow-y: auto;
            --APopStep: calc(var(--NGap) * 0.2);
            --APopSize: 0.92rem;
            }
        }


/* [MODE D] =================================================================
   Portrait, 500px or less. A phone upright. Most of your visitors.

   TWO COLUMNS, ALWAYS, AND THEY FILL THE SCREEN EXACTLY. Rather than an ideal
   with a floor and a ceiling, the cell here is solved backwards: take the
   window, subtract the two gutters and the one gap, halve it. No leftover at
   all. Your 1.5in floor and 2.5in ceiling still wrap it.

       320 wide -> 152px = 1.58in       390 wide -> 187px = 1.95in
       360 wide -> 172px = 1.79in       430 wide -> 207px = 2.16in
       500 wide -> 240px = 2.50in, the ceiling, exactly

   THE COLLAPSE IS A MAP, NOT A FLATTENING. v1 collapsed every tile to 1x1 on
   a phone, throwing the whole hierarchy away on the device most people use.
   Here the sizes map DOWN: the important pieces stay bigger than the rest.
       3x3, 2x3, 3x2 -> 2x2      4x1, 3x1 -> 2x1      1x3 -> 1x2
   ========================================================================= */

    @media (orientation: portrait) and (max-width: 500px) {

        body.ArtPage {
            --APadX: 10px;
            --AFloatD: clamp(3rem, 9vh, 3.9rem);
            }

    /*  TWO COLUMNS, ALWAYS, FILLING THE SCREEN EXACTLY. The script works the
        cell out from the width available; these three numbers only tell it
        the range you allow and roughly what to aim for. Aiming at half the
        window is what pins it to two columns on every phone from 320 up.  */
        .ArtGrid {
            --AGridGap: 4px;
            --ACellMin: 1.5in;
            --ACell:    calc((100vw - (var(--APadX) * 2) - 4px) / 2);
            --ACellMax: 2.5in;
            }

        .s-3x3 { grid-column-end: span 2; grid-row-end: span 2; }
        .s-2x3 { grid-column-end: span 2; grid-row-end: span 2; }
        .s-3x2 { grid-column-end: span 2; grid-row-end: span 2; }
        .s-3x1 { grid-column-end: span 2; grid-row-end: span 1; }
        .s-4x1 { grid-column-end: span 2; grid-row-end: span 1; }
        .s-1x3 { grid-column-end: span 1; grid-row-end: span 2; }

    /*  The bar becomes two rows: logo and language on the first, the five
        filters on a horizontal scroller below. They scroll rather than wrap
        so the bar cannot grow to four lines and push the art off the screen,
        which is the thing you are trying to stop.                         */
        .ArtBar {
            flex-wrap: wrap;
            gap: calc(var(--NGap) * 0.6) 0.75rem;
            padding-block: calc(var(--NGap) * 0.7);
            }

        .ArtBarWords {
            flex-wrap: wrap;
            row-gap: calc(var(--NGap) * 0.55);
            }

        .ArtFilters {
            order: 10;
            flex-basis: 100%;
            flex-wrap: nowrap;
            overflow-x: auto;
            scrollbar-width: none;
            gap: 1rem;
            }

        .ArtFilters::-webkit-scrollbar { display: none; }

        .ArtTicker {
            font-size: clamp(1rem, 5vw, 1.4rem);
            padding-block: calc(var(--NGap) * 0.8);
            }

    /*  Captions off by default: at 187px a tile is small and a tap opens the
        artwork, where the title is set properly.                          */
        .ArtCard.s-2x2 .ArtCap,
        .ArtCard.s-3x3 .ArtCap,
        .ArtCard.s-3x2 .ArtCap,
        .ArtCard.s-2x3 .ArtCap {
            transform: translateY(101%);
            }

    /*  THE COPYRIGHT GOES UNDER THE FLOATS RATHER THAN BESIDE THEM. At this
        width there is no room for both across, so the strip drops below the
        cluster instead of being pushed off the screen by it.              */
        .ArtFoot {
            padding-inline-start: calc(var(--APadX) * 1.25); /*  Original var(--APadX) */
            padding-bottom: calc(var(--AFloatBoxH) + var(--NGap));
            }

        .ArtPop {
            width: calc(100vw - var(--APadX) * 2);
            }
        }


/* [A15 FARSI] ==============================================================
   [A15 FARSI]
   Persian. READ THIS ONE, because this page behaves differently from index.
   --------------------------------------------------------------------------
   >>> THE LAYOUT DOES NOT FLIP. <<< You asked that everything stay exactly
   where it is when the language changes: the logo stays top left, the filter
   words stay in the same order in the same place, the tabs stay, EN and فا
   stay on the right. Only the WORDS change.

   Negar-JS.js [S2 LANG] still sets dir="rtl" on the document, because that is
   correct for the language and screen readers need it. This page simply pins
   its own frame back to ltr so nothing moves. That is why every rule below
   names direction rather than swapping margins around.

   THE ONE EXCEPTION IS THE I STATEMENT, which you wanted right-aligned in
   Farsi, level with the EN / فا switch. It is the only element on the page
   that changes side, and it lines up with the switch because they share
   --APadX as their gutter.

   THE STANDING "I" DISAPPEARS IN FARSI. Your Persian lines already open with
   من, so an English I in front of them would be wrong. Art-JS.js [T1 TYPER]
   also fades rather than types in Farsi: Persian letters join, and a
   half-typed word renders in disconnected letterforms and looks broken.

   Farsi runs at 85% of the English size, the same --NFaScale idea index uses.
   ========================================================================= */

    html[dir="rtl"] body.ArtPage,
    html[dir="rtl"] .ArtBar,
    html[dir="rtl"] .ArtBarWords,
    html[dir="rtl"] .ArtFilters,
    html[dir="rtl"] .ArtTabs,
    html[dir="rtl"] .ArtLang,
    html[dir="rtl"] .ArtGrid,
    html[dir="rtl"] .ArtFoot,
    html[dir="rtl"] .ArtFloat,
    html[dir="rtl"] .ArtTop {
        direction: ltr;
        }

/*  The statement box and the menu DO read right to left, because they are
    running text and lists of words rather than a frame.                   */

    html[dir="rtl"] .ArtPop {
        direction: rtl;
        text-align: right;
        }

/*  THE TICKER, the one thing that changes side.                           */

    html[dir="rtl"] .ArtTicker {
        direction: rtl;
        text-align: right;
        }

    html[lang="fa"] .ArtI {
        display: none;
        }

    html[lang="fa"] .ArtCaret {
        display: none;
        }

    html[lang="fa"] .ArtType {
        transition: opacity 0.35s var(--NEase);
        }

/*  The Persian face, and 85% of the English size.                          */

    html[lang="fa"] .ArtFilterBtn,
    html[lang="fa"] .ArtTab,
    html[lang="fa"] .ArtTicker,
    html[lang="fa"] .ArtFloatLabel,
    html[lang="fa"] .ArtCopyright,
    html[lang="fa"] .ArtPop,
    html[lang="fa"] .ArtCap {
        font-family: var(--NFontFA);
        font-size: 0.85em;
        line-height: 1.9;
        }

/*  The captions inside the tiles read right to left even though the wall
    does not move.                                                         */

    html[dir="rtl"] .ArtCap {
        direction: rtl;
        text-align: right;
        }


/* [A16 MOTION] =============================================================
   [A16 MOTION]
   Anyone who has asked their system to reduce motion gets a still page: no
   typing, no blinking caret, no zoom on hover, no smooth scroll. The caption
   still appears, it just appears rather than slides. Nothing is lost except
   movement.
   ========================================================================= */

    @media (prefers-reduced-motion: reduce) {

        html { scroll-behavior: auto; }

        .ArtThumb, .ArtCap, .ArtFloat, .ArtTop,
        .ArtPop, .ArtFloatBtn, .ArtBurger span {
            transition: none !important;
            }

        .ArtCard:hover .ArtThumb { transform: none; }

        .ArtCaret { animation: none; }
        }

/* ==========================================================================
   END OF Art.css
   ========================================================================== */
