/*
 * FRAME - screen 1: the current photo in a light-oak frame on a dark,
 * museum-lit wall. Screen 2 (the auction) is styled in styles.css; this file
 * loads after it. Only img#hero is content here: .wall, .frame and .glass
 * are decorative (aria-hidden, pointer-events: none) and screen 1 must stay
 * free of text, buttons and labels.
 *
 * AICODE-NOTE: dist/wall.css is GENERATED - never edit it by hand. The rules
 * live in tools/wall/wall.template.css, the frame profile and textures in
 * tools/wall/gen.py; run `python3 tools/wall/gen.py` from the repo root.
 */
:root {
  --vh: 1vh;
  /* Scene unit: frame, shadows and wall details all scale with it, so a
     phone shows the same scene as a desktop, just smaller. */
  --u: 1vmin;

  /* Light-oak moulding; the photo sits directly in it (no passe-partout). */
  --fw: clamp(13px, 3vmin, 34px);
  /* Dark oak under the rails: the only thing that can show through the
     anti-aliased seams (mitre joints, rail/photo edge), so a seam reads as a
     joint or the rabbet's shadow, never as a light hairline. */
  --frame-core: #6b4d2e;

  /* Wall around the frame; the bottom margin is larger, so the picture
     hangs slightly above the centre of the screen. */
  --gx: max(22px, 7vw);
  --gt: max(24px, calc(var(--vh) * 7));
  --gb: max(32px, calc(var(--vh) * 10));

  /* Light: shadow colour/strength, light falloff over the frame, reflection
     strength of the glass (low: the room around the spot is dark). */
  --sh: 0 0 0;
  --sh-a: .78;
  --fall: 1.7;
  --glare: .6;
}

@supports (height: 1svh) {
  :root {
    --vh: 1svh;
  }
}

/* ---------- Screen 1 layout ---------- */

/*
 * AICODE-NOTE: Screen 1 is exactly 100vh on purpose, NOT dvh/svh. On mobile
 * browsers 100vh equals the *large* viewport (toolbars retracted) and never
 * changes while scrolling:
 * - while the toolbar is visible the wall just extends under/below it, so
 *   nothing from screen 2 peeks in at the bottom (svh would leave a strip of
 *   screen 2 visible once the toolbar collapses);
 * - the layout does not reflow when the toolbar collapses/expands (dvh would
 *   resize both screens mid-scroll and make the snap points jump).
 * The PICTURE, however, is laid out in the *small* viewport (--vh = 1svh):
 * the extra bottom padding (100vh - 100svh) keeps the whole frame inside the
 * part of screen 1 that is visible while the toolbar is shown.
 */
.screen-photo {
  position: relative;
  box-sizing: border-box;
  height: 100vh;
  padding: var(--gt) var(--gx) calc(var(--gb) + 100vh - 100 * var(--vh));
  display: grid;
  place-items: center;
  overflow: hidden;
  overflow: clip;
  /* cqw/cqh below = this content box, i.e. the space left for the picture */
  container-type: size;
  background: #141517;
}

.wall,
.wall::after {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.wall::after {
  content: "";
}

/*
 * AICODE-NOTE: Shrink-wrap sizing. img#hero keeps width/height: auto and is
 * only limited by max-width / max-height, so the browser scales it down with
 * its natural aspect ratio (never cropped, never stretched) and the frame
 * wraps the image instead of the screen, whatever its proportions. The
 * limits are the space left after wall margins (the container's content box)
 * minus the moulding on each side. Images smaller than that are shown at
 * their natural size (a smaller print on the same wall), never upscaled.
 */
#hero {
  display: block;
  width: auto;
  height: auto;
  max-width: calc(100vw - 2 * (var(--gx) + var(--fw)));
  max-height: calc(100 * var(--vh) - var(--gt) - var(--gb) - 2 * var(--fw));
  max-width: calc(100cqw - 2 * var(--fw));
  max-height: calc(100cqh - 2 * var(--fw));
}

/*
 * AICODE-NOTE: Light model. One museum spot hangs above the picture, in
 * front of the wall:
 * - .wall::after darkens the wall away from a pool of light centred a bit
 *   above the picture (multiplying by darkness keeps the texture contrast
 *   physically right; adding white would wash it out);
 * - the frame's wall shadow falls DOWN (four layered shadows: contact, cast,
 *   penumbra, ambient), deep because the wall is dark (--sh, --sh-a);
 * - the rails are shaded from the moulding's cross-section for that same
 *   light (generated gradients at the end of this file), plus --fall-*
 *   falloff along each rail;
 * - the frame lip shades the top edge of the photo (.glass inset shadow).
 */
.artwork {
  position: relative;
  padding: var(--fw);
  background: var(--frame-core);
  box-shadow:
    0 calc(var(--u) * .1) calc(var(--u) * .18) rgb(var(--sh) / calc(var(--sh-a) * 1.1)),
    0 calc(var(--u) * .8) calc(var(--u) * 1.2) calc(var(--u) * -.2) rgb(var(--sh) / calc(var(--sh-a) * .8)),
    0 calc(var(--u) * 2.4) calc(var(--u) * 4) calc(var(--u) * -.6) rgb(var(--sh) / calc(var(--sh-a) * .62)),
    0 calc(var(--u) * 5.5) calc(var(--u) * 9) calc(var(--u) * -1.5) rgb(var(--sh) / calc(var(--sh-a) * .32));
}

/* ---------- Frame rails ---------- */

/* Four mitred rails: each one is a trapezoid, so the joints meet at 45deg
   like a real moulding, and each rail is shaded for its own side. */
.frame {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.rail {
  position: absolute;
  display: block;
  background-blend-mode: normal, hard-light, normal;
}

.rail-t {
  top: 0;
  left: 0;
  right: 0;
  height: var(--fw);
  clip-path: polygon(0 0, 100% 0, calc(100% - var(--fw)) 100%, var(--fw) 100%);
}

.rail-b {
  bottom: 0;
  left: 0;
  right: 0;
  height: var(--fw);
  clip-path: polygon(var(--fw) 0, calc(100% - var(--fw)) 0, 100% 100%, 0 100%);
}

.rail-l {
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--fw);
  clip-path: polygon(0 0, 100% var(--fw), 100% calc(100% - var(--fw)), 0 100%);
}

.rail-r {
  top: 0;
  bottom: 0;
  right: 0;
  width: var(--fw);
  clip-path: polygon(0 var(--fw), 100% 0, 100% 100%, 0 calc(100% - var(--fw)));
}

/* Light falloff along each rail: the pool of light is centred above the
   picture, so corners and the bottom rail get a little less light. */
:root {
  --fall-t: linear-gradient(to right, rgb(0 0 0 / calc(var(--fall) * .14)), rgb(0 0 0 / 0) 34% 66%, rgb(0 0 0 / calc(var(--fall) * .14)));
  --fall-b: linear-gradient(to right, rgb(0 0 0 / calc(var(--fall) * .26)), rgb(0 0 0 / calc(var(--fall) * .1)) 34% 66%, rgb(0 0 0 / calc(var(--fall) * .26)));
  --fall-s: linear-gradient(to bottom, rgb(0 0 0 / calc(var(--fall) * .05)), rgb(0 0 0 / 0) 22%, rgb(0 0 0 / calc(var(--fall) * .1)) 70%, rgb(0 0 0 / calc(var(--fall) * .24)));
}

/* Light oak: straight grain along each rail (a different piece of wood per
   rail) over the shaded profile. */
.rail-t {
  background: var(--fall-t), var(--tex-oak-h) 0 0 / calc(var(--fw) * 14) var(--fw), linear-gradient(to bottom, var(--oak-t));
}

.rail-b {
  background: var(--fall-b), var(--tex-oak-h) 37% 0 / calc(var(--fw) * 14) var(--fw), linear-gradient(to top, var(--oak-b));
}

.rail-l {
  background: var(--fall-s), var(--tex-oak-v) 0 61% / var(--fw) calc(var(--fw) * 14), linear-gradient(to right, var(--oak-s));
}

.rail-r {
  background: var(--fall-s), var(--tex-oak-v) 0 13% / var(--fw) calc(var(--fw) * 14), linear-gradient(to left, var(--oak-s));
}

/* ---------- Glass ---------- */

/* Glass over the photo: the frame lip's shadow on the photo (top, a little
   on the sides) and a faint reflection of the room. */
.glass {
  position: absolute;
  inset: var(--fw);
  pointer-events: none;
  box-shadow:
    inset 0 calc(var(--u) * .5) calc(var(--u) * .8) calc(var(--u) * -.2) rgb(0 0 0 / .3),
    inset 0 0 calc(var(--u) * .3) rgb(0 0 0 / .22);
  background:
    linear-gradient(115deg, rgb(255 255 255 / 0) 24%, rgb(255 255 255 / calc(var(--glare) * .065)) 36%, rgb(255 255 255 / calc(var(--glare) * .02)) 45%, rgb(255 255 255 / 0) 52%),
    linear-gradient(115deg, rgb(255 255 255 / 0) 63%, rgb(255 255 255 / calc(var(--glare) * .03)) 69%, rgb(255 255 255 / 0) 74%),
    linear-gradient(to bottom, rgb(255 255 255 / calc(var(--glare) * .035)), rgb(255 255 255 / 0) 28%);
}

/* ---------- Wall ---------- */

/* Graphite wall in a dark room, one museum spot on the picture: fine grain
   and a soft relief, darkened outside the pool of light. */
.wall {
  background:
    var(--tex-grain) 0 0 / 200px,
    var(--tex-dark) center / calc(var(--u) * 70),
    #4a4b4e;
  background-blend-mode: hard-light, hard-light;
}

.wall::after {
  background:
    radial-gradient(ellipse calc(var(--u) * 74) calc(var(--u) * 70) at 50% calc(var(--vh) * 45), rgb(10 11 14 / 0), rgb(10 11 14 / .1) 38%, rgb(8 9 12 / .55) 70%, rgb(6 7 9 / .86) 100%);
}

/* ---------- Generated tokens (frame profile, textures) ----------
 * AICODE-NOTE: Written by tools/wall/gen.py - change the constants there and
 * rerun `python3 tools/wall/gen.py` from the repo root instead of editing
 * these values. The profile gradients are shaded for the same single light
 * as the rest of this file; textures are SVG feTurbulence tiles the browser
 * rasterises once (no live CSS filters), greys centred on 50% for hard-light.
 */
:root {
  --oak-t: #d5aa73 0%, #daad75 0.621%, #ddb078 1.862%, #dfb480 6%, #dab07d 8.483%, #caa16f 12%, #c79f6d 12%, #bc9565 78%, #b89363 78%, #997950 82.552%, #896c48 84.207%, #745b3b 86.069%, #725a3b 90%, #705839 90%, #5f4a30 100%;
  --oak-b: #71593a 0%, #735b3b 5.172%, #886b47 6.621%, #987850 8.069%, #b89363 12%, #bc9565 12%, #c79f6d 78%, #caa16f 78%, #d8ae7b 81.517%, #deb380 83.793%, #e0b47e 86.483%, #deb178 90%, #dcb17b 90%, #cca371 100%;
  --oak-s: #856945 0%, #8e704a 0.414%, #997951 1.241%, #a38156 2.276%, #ab885b 3.724%, #b99363 7.448%, #c19a68 12%, #c19a68 78%, #bc9665 81.724%, #b48f60 85.241%, #ab875b 87.931%, #9f7e54 90%, #ab875b 90%, #9b7b52 100%;
  --tex-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Cfilter id='f' filterUnits='userSpaceOnUse' x='-24' y='-24' width='248' height='248' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' seed='5' stitchTiles='stitch' x='0' y='0' width='200' height='200' result='n_'/%3E%3CfeTile in='n_' result='n'/%3E%3CfeColorMatrix in='n' values='0.13 0 0 0 0.435 0.13 0 0 0 0.435 0.13 0 0 0 0.435 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23f)'/%3E%3C/svg%3E");
  --tex-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600' viewBox='0 0 600 600'%3E%3Cfilter id='f' filterUnits='userSpaceOnUse' x='-24' y='-24' width='648' height='648' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.035' numOctaves='4' seed='6' stitchTiles='stitch' x='0' y='0' width='600' height='600' result='r_'/%3E%3CfeTile in='r_' result='r'/%3E%3CfeColorMatrix in='r' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0' result='rh'/%3E%3CfeOffset in='rh' dy='-1.4' result='eo'/%3E%3CfeComposite in='eo' in2='rh' operator='arithmetic' k2='0.5' k3='-0.5' k4='0.5' result='e'/%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.005' numOctaves='3' seed='12' stitchTiles='stitch' x='0' y='0' width='600' height='600' result='m_'/%3E%3CfeTile in='m_' result='m'/%3E%3CfeColorMatrix in='m' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0 0 0 0.46' result='ma'/%3E%3CfeComposite in='e' in2='ma' operator='arithmetic' k2='1' k3='1' k4='-0.5' result='o'/%3E%3CfeColorMatrix values='0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='600' height='600' filter='url(%23f)'/%3E%3C/svg%3E");
  --tex-oak-h: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1400' height='100' viewBox='0 0 1400 100'%3E%3Cfilter id='f' filterUnits='userSpaceOnUse' x='-24' y='-24' width='1448' height='148' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0025 0.06' numOctaves='3' seed='3' stitchTiles='stitch' x='0' y='0' width='1400' height='100' result='a_'/%3E%3CfeTile in='a_' result='a'/%3E%3CfeColorMatrix in='a' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0 0 0 0.35' result='aa'/%3E%3CfeTurbulence type='turbulence' baseFrequency='0.0016 0.3' numOctaves='2' seed='10' stitchTiles='stitch' x='0' y='0' width='1400' height='100' result='b_'/%3E%3CfeTile in='b_' result='b'/%3E%3CfeColorMatrix in='b' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 0 0 0 1.05' result='ln'/%3E%3CfeComposite in='aa' in2='ln' operator='arithmetic' k2='1' k3='-0.1' k4='0.012'/%3E%3CfeColorMatrix values='0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='1400' height='100' filter='url(%23f)'/%3E%3C/svg%3E");
  --tex-oak-v: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='1400' viewBox='0 0 100 1400'%3E%3Cfilter id='f' filterUnits='userSpaceOnUse' x='-24' y='-24' width='148' height='1448' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.06 0.0025' numOctaves='3' seed='3' stitchTiles='stitch' x='0' y='0' width='100' height='1400' result='a_'/%3E%3CfeTile in='a_' result='a'/%3E%3CfeColorMatrix in='a' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0 0 0 0.35' result='aa'/%3E%3CfeTurbulence type='turbulence' baseFrequency='0.3 0.0016' numOctaves='2' seed='10' stitchTiles='stitch' x='0' y='0' width='100' height='1400' result='b_'/%3E%3CfeTile in='b_' result='b'/%3E%3CfeColorMatrix in='b' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 0 0 0 1.05' result='ln'/%3E%3CfeComposite in='aa' in2='ln' operator='arithmetic' k2='1' k3='-0.1' k4='0.012'/%3E%3CfeColorMatrix values='0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='100' height='1400' filter='url(%23f)'/%3E%3C/svg%3E");
}
