@import url("fonts.css");

/* ==========================================================================
   kaddari.net — site stylesheet
   ==========================================================================

   HOW THE PAGE IS PUT TOGETHER
   ----------------------------
   Every page is the same nesting of five elements:

     .page-container     positioning shell; owns the per-page CSS variables
       .page             the centred column — its width is --content-width
         .page-body      the padded typographic box
           .page-content your actual content (grid rows, text, images)
       .page-bg          the flat colour behind the page

   Header and footer are the same structure wrapped in .pin--top / .pin--bottom.

   ABOUT rem UNITS
   ---------------
   Everything is sized in rem, and the root font-size is set by JavaScript
   from the viewport size (see assets/js/site.js). That is what makes the
   whole design scale as one piece, and it is why the mobile layout looks
   noticeably different rather than merely narrower. Roughly:

     wide screens   1rem ≈ 0.0144 × viewport height
     phones         1rem ≈ 16px and up

   So a value like 1.7rem stays visually proportional at any window size.

   EDITING
   -------
   Per-page settings (colours, widths, type sizes) live in a <style> block
   at the top of each .html file. Shared rules live here.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Reset and document
   -------------------------------------------------------------------------- */

html {
	margin: 0;
	padding: 0;
	min-height: 100vh;
	position: relative;
	background-color: #fff;
	touch-action: manipulation;
	/* font-size is set inline by site.js — see the note above */
}

body {
	margin: 0;
	padding: 0;
	background-color: #fff;
	color: #000;
	-moz-osx-font-smoothing: grayscale;
	-webkit-font-smoothing: antialiased;
	-webkit-text-size-adjust: none;
}

body.no-scroll { overflow: hidden; }

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

:focus { outline: 0; }

img {
	border: 0;
	padding: 0;
	max-width: 100%;
}


/* --------------------------------------------------------------------------
   2. Page skeleton
   --------------------------------------------------------------------------
   The defaults below are overridden per page. Every variable a page may set
   is listed here with the value it falls back to.
   -------------------------------------------------------------------------- */

.page-container {
	/* layout */
	--content-width      : 100%;      /* width of the centred column        */
	--page-align         : flex-start;/* vertical position of the content   */
	--page-text-align    : left;      /* horizontal alignment of the text   */
	--page-margin-left   : auto;      /* set to 0 to pin the column left    */
	--page-min-height    : auto;      /* usually 100vh                      */
	--page-bg            : transparent;

	/* padding around the content (mobile value is applied under .is-mobile) */
	--page-padding       : 1.5rem;
	--page-padding-mobile: 0.8rem;

	/* type */
	--text-size          : 1.6rem;
	--text-leading       : 1.3;
	--h1-size            : 2.8rem;
	--h1-leading         : 1.1;
	--h2-size            : 3rem;
	--h2-leading         : 1.1;
	--h2-link-color      : rgba(0, 0, 0, 0.85);
	--small-size         : 1.3rem;
	--small-leading      : 1.3;
	--small-color        : rgba(0, 0, 0, 0.75);

	position: relative;
	overflow: visible;
	width: 100%;
}

.page {
	position: relative;
	z-index: 2;

	display: flex;
	flex-wrap: wrap;
	align-items: var(--page-align);

	width: var(--content-width);
	max-width: 100%;
	margin-left: var(--page-margin-left);
	margin-right: auto;
	min-height: var(--page-min-height);

	overflow: visible;
	text-align: var(--page-text-align);
	word-wrap: break-word;
}

.page-body {
	flex: 1 0 auto;
	max-width: 100%;
	padding: var(--page-padding);
}

.page-content::after {           /* clearfix */
	content: "";
	display: table;
	clear: both;
}

.page-bg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-color: var(--page-bg);
}

.site {
	position: relative;
	width: 100%;
	min-height: 100vh;
	overflow: hidden;
}


/* --------------------------------------------------------------------------
   3. Pinned header and footer
   --------------------------------------------------------------------------
   The header is fixed over the page and spans the full viewport height, which
   is how it behaves on the original site. It is pointer-events:none so that
   it cannot swallow clicks meant for the content underneath — its own links
   stay clickable. (On the Cargo original it did swallow them, which made
   links and audio players below the fold unclickable.)
   -------------------------------------------------------------------------- */

.pin {
	position: relative;
	width: 100%;
}

.pin--top > .page-container {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 4;
	pointer-events: none;
}

.pin--bottom { height: 0; }

.pin--bottom > .page-container {
	position: absolute;
	left: 0;
	bottom: 0;
	z-index: 4;
}

/* Let clicks through the fixed header, but keep its own controls live. */
.pin--top .page-content a,
.pin--top .page-content button,
.pin--top .page-content iframe,
.pin--top .page-content img,
.pin--top .page-content input,
.pin--top .page-content video { pointer-events: auto; }


/* --------------------------------------------------------------------------
   4. Typography
   -------------------------------------------------------------------------- */

.page-body {
	font-family: "Alegreya Sans", Icons, sans-serif;
	font-size: var(--text-size);
	font-style: normal;
	font-weight: 400;
	line-height: var(--text-leading);
	color: rgba(0, 0, 0, 0.75);
}

.page-body a {
	color: rgba(0, 0, 0, 0.75);
	padding-bottom: 0;
	border-bottom: 2px solid rgba(12, 12, 12, 0.6);
	text-decoration: none;
}

a:active { opacity: 0.7; }

.page a.active { color: rgba(0, 0, 0, 0.85); }

.page-body a.image-link,
.page-body a.icon-link {
	border-bottom: 0;
	padding-bottom: 0;
}

/* The three heading/label styles are scoped to .page-body so that their link
   colours beat the generic link rule above, the way they did on the original. */

.page-body h1 {
	margin: 0;
	padding: 0;
	font-family: "Plex Sans", Icons, sans-serif;
	font-size: var(--h1-size);
	font-style: normal;
	font-weight: 700;
	line-height: var(--h1-leading);
	color: rgba(0, 0, 0, 1);
}

.page-body h1 a {
	color: rgba(255, 255, 0, 1);
	text-decoration: none;
}

.page-body h2 {
	margin: 0;
	padding: 0;
	font-family: "Helvetica Neue", Icons, sans-serif;
	font-size: var(--h2-size);
	font-style: normal;
	font-weight: 400;
	line-height: var(--h2-leading);
	letter-spacing: 0.01em;
	color: rgba(0, 0, 0, 0.85);
}

.page-body h2 a { color: var(--h2-link-color); }

.page-body small {
	display: inline-block;
	max-width: 100%;
	font-family: "TeX Gyre Heros Condensed", Icons, sans-serif;
	font-size: var(--small-size);
	font-style: normal;
	font-weight: 400;
	line-height: var(--small-leading);
	letter-spacing: 0.07em;
	color: var(--small-color);
	text-decoration: inherit;
}

.page-body small a {
	color: rgba(0, 0, 0, 0.85);
	border-bottom-width: 0;
}

i, em     { font-style: italic; }
b, strong { font-weight: bolder; }

sub, sup { position: relative; vertical-align: baseline; }
sub { top:  0.3em; }
sup { top: -0.4em; }

s { text-decoration: line-through; }
s * { text-transform: inherit; }

ul, ol {
	margin: 0;
	padding: 0 0 0 4.5rem;
}

ol > li { padding-left: 0.75rem; }

blockquote {
	margin: 0;
	padding: 0 0 0 2em;
}

hr {
	display: block;
	height: 1px;
	border: 0;
	background: rgba(0, 0, 0, 0.11);
}

/* <p> keeps the browser's default 1em margin, as it did on the original —
   the Mondograph page relies on it for the gap between paragraphs. */


/* --------------------------------------------------------------------------
   5. The 12-column grid
   --------------------------------------------------------------------------
   Content markup uses these attributes, exactly as the original did:

     <div grid-row grid-pad="2" grid-gutter="4" grid-responsive>
       <div grid-col="4" grid-pad="2"> … </div>
     </div>

     grid-col="1".."12"   twelfths of the row
     grid-col="x1".."x12" fractions: x12 = 1/1, x11 = 1/2, x10 = 1/3, x9 = 1/4 …
     grid-pad="N"         padding inside each cell, in half-rem steps
     grid-gutter="N"      negative margin on the row, cancelling the outer pad
     grid-responsive      stack the cells full-width on mobile
   -------------------------------------------------------------------------- */

[grid-row] {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	box-sizing: border-box;
}

[grid-col] { box-sizing: border-box; }

[grid-col="auto"] { flex: 1; }

[grid-col="1"]  { width:  8.33333%; }
[grid-col="2"]  { width: 16.66667%; }
[grid-col="3"]  { width: 25%;       }
[grid-col="4"]  { width: 33.33333%; }
[grid-col="5"]  { width: 41.66667%; }
[grid-col="6"]  { width: 50%;       }
[grid-col="7"]  { width: 58.33333%; }
[grid-col="8"]  { width: 66.66667%; }
[grid-col="9"]  { width: 75%;       }
[grid-col="10"] { width: 83.33333%; }
[grid-col="11"] { width: 91.66667%; }
[grid-col="12"] { width: 100%;      }

[grid-col="x12"] { width: 100%;          }
[grid-col="x11"] { width: 50%;           }
[grid-col="x10"] { width: 33.33%;        }
[grid-col="x9"]  { width: 25%;           }
[grid-col="x8"]  { width: 20%;           }
[grid-col="x7"]  { width: 16.666666667%; }
[grid-col="x6"]  { width: 14.285714286%; }
[grid-col="x5"]  { width: 12.5%;         }
[grid-col="x4"]  { width: 11.111111111%; }
[grid-col="x3"]  { width: 10%;           }
[grid-col="x2"]  { width:  9.090909091%; }
[grid-col="x1"]  { width:  8.333333333%; }

[grid-pad="0"]    { padding: 0;       }
[grid-pad="0.25"] { padding: 0.125rem;}
[grid-pad="0.5"]  { padding: 0.25rem; }
[grid-pad="0.75"] { padding: 0.375rem;}
[grid-pad="1"]    { padding: 0.5rem;  }
[grid-pad="1.25"] { padding: 0.625rem;}
[grid-pad="1.5"]  { padding: 0.75rem; }
[grid-pad="1.75"] { padding: 0.875rem;}
[grid-pad="2"]    { padding: 1rem;    }
[grid-pad="2.5"]  { padding: 1.25rem; }
[grid-pad="3"]    { padding: 1.5rem;  }
[grid-pad="3.5"]  { padding: 1.75rem; }
[grid-pad="4"]    { padding: 2rem;    }
[grid-pad="5"]    { padding: 2.5rem;  }
[grid-pad="6"]    { padding: 3rem;    }
[grid-pad="7"]    { padding: 3.5rem;  }
[grid-pad="8"]    { padding: 4rem;    }
[grid-pad="9"]    { padding: 4.5rem;  }
[grid-pad="10"]   { padding: 5rem;    }

[grid-gutter="0"]   { margin: 0;        }
[grid-gutter="0.5"] { margin: -0.25rem; }
[grid-gutter="1"]   { margin: -0.5rem;  }
[grid-gutter="1.5"] { margin: -0.75rem; }
[grid-gutter="2"]   { margin: -1rem;    }
[grid-gutter="2.5"] { margin: -1.25rem; }
[grid-gutter="3"]   { margin: -1.5rem;  }
[grid-gutter="3.5"] { margin: -1.75rem; }
[grid-gutter="4"]   { margin: -2rem;    }
[grid-gutter="5"]   { margin: -2.5rem;  }
[grid-gutter="6"]   { margin: -3rem;    }
[grid-gutter="7"]   { margin: -3.5rem;  }
[grid-gutter="8"]   { margin: -4rem;    }
[grid-gutter="10"]  { margin: -5rem;    }
[grid-gutter="12"]  { margin: -6rem;    }
[grid-gutter="14"]  { margin: -7rem;    }
[grid-gutter="16"]  { margin: -8rem;    }
[grid-gutter="18"]  { margin: -9rem;    }
[grid-gutter="20"]  { margin: -10rem;   }


/* --------------------------------------------------------------------------
   6. Media inside content
   -------------------------------------------------------------------------- */

/* Images fill the grid column they sit in, keeping their own proportions —
   the same as the original, which resized them with JavaScript. */
.page-content img {
	float: none;
	margin-bottom: 0;
	vertical-align: bottom;
	width: 100%;
	height: auto;
}

/* <small> is inline-block and shrinks to its contents, so an image inside one
   would have no width to fill. When a <small> holds nothing but a picture,
   give it the full column. */
.page-content small:has(> img:only-child) { width: 100%; }

/* Embeds keep the size given by their width/height attributes and shrink to
   fit when the column is narrower — which is what the original did with
   JavaScript. They stay inline (rather than block) so they keep sitting on
   the text baseline: that leaves a few pixels underneath which the
   surrounding layout was built around. */
.page-content iframe {
	max-width: 100%;
	border: 0;
}

/* Vimeo and YouTube embeds keep their 16:9 shape as they shrink. */
iframe.video-embed {
	aspect-ratio: 16 / 9;
	height: auto;
}


/* --------------------------------------------------------------------------
   6b. Audio player
   --------------------------------------------------------------------------
   Markup:  <div class="audio-player" data-src="…mp3" data-title="Track name">
   The controls are built by site.js. Before it runs the element is empty, so
   it takes up no space and nothing flashes.
   -------------------------------------------------------------------------- */

.audio-player {
	display: flex;
	align-items: stretch;
	width: 100%;
	max-width: 26rem;
	height: 3.3rem;
	margin: 1px 1px 1em 1px;
	outline: 1px solid rgba(0, 0, 0, 0.15);
	background: transparent;
	color: rgba(0, 0, 0, 0.6);
	font-family: "TeX Gyre Heros Condensed", Icons, sans-serif;
	font-size: 1.2rem;
	line-height: 1.3;
	text-align: left;
	user-select: none;
}

.audio-player:empty { display: none; }

.audio-player .button {
	flex: 0 0 3.8rem;
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 0;
	padding: 0;
	cursor: pointer;
	fill: rgba(0, 0, 0, 0.85);
}

.audio-player .button svg {
	width: 34%;
	height: 34%;
	min-width: 8px;
}

.audio-player .separator {
	flex: 0 0 1px;
	background-color: rgba(0, 0, 0, 0.15);
}

.audio-player .bar {
	position: relative;
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	min-width: 0;
	cursor: pointer;
}

.audio-player .buffer {
	position: absolute;
	top: 0; left: 0; bottom: 0;
	width: 0;
	background: rgba(0, 0, 0, 0.03);
}

.audio-player .progress {
	position: absolute;
	top: 0; left: 0; bottom: 0;
	width: 0;
	background: rgba(0, 0, 0, 0.1);
}

.audio-player .progress-indicator {
	position: absolute;
	right: 0;
	width: 1px;
	height: 100%;
	border: 1px solid rgba(0, 0, 0, 0.7);
}

.audio-player .title,
.audio-player .current-time,
.audio-player .total-time {
	position: relative;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.audio-player .title        { flex: 1 1 auto; padding-left: 1rem; }
.audio-player .current-time { padding-left: 1rem; }
.audio-player .total-time   { padding-right: 1rem; padding-left: 0.6rem; }

.audio-player .note-icon {
	flex: 0 0 3.8rem;
	height: 100%;
	padding: 1rem;
	fill: rgba(0, 0, 0, 0.5);
}

.audio-player.is-playing .title { display: none; }
.audio-player:not(.is-playing) .current-time { display: none; }

.is-mobile .audio-player { max-width: 100%; }


/* --------------------------------------------------------------------------
   7. Slideshow
   --------------------------------------------------------------------------
   Markup:

     <div class="slideshow" data-autoplay="2.8" data-speed="0.5"
          data-transition="fade|slide" data-constrain-height="true">
       <img src="…" width="1200" height="800" alt="">
       …
     </div>

     data-autoplay        seconds between slides; omit or "0" to hold still
     data-speed           seconds the transition takes
     data-transition      "fade" cross-dissolves, "slide" pushes sideways
     data-constrain-height keeps every slide the height of the first one

   Arrows appear on hover; the left and right halves are click targets.
   -------------------------------------------------------------------------- */

.slideshow {
	position: relative;
	width: 100%;
	overflow: hidden;
	touch-action: pan-y;
}

.slideshow__track {
	display: flex;
	width: 100%;
	will-change: transform;
}

.slideshow__slide {
	flex: 0 0 100%;
	width: 100%;
	min-width: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
}

.slideshow__slide img {
	display: block;
	width: 100%;
	height: auto;
}

/* constrain-height: every slide is letterboxed into the same box */
.slideshow[data-constrain-height="true"] .slideshow__slide img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: center center;
}

/* fade transition: slides stack and cross-dissolve */
.slideshow[data-transition="fade"] .slideshow__track {
	display: block;
	position: relative;
}

.slideshow[data-transition="fade"] .slideshow__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity var(--slideshow-speed, 0.5s) ease-in-out;
}

.slideshow[data-transition="fade"] .slideshow__slide:first-child { position: relative; }

.slideshow[data-transition="fade"] .slideshow__slide.is-current {
	opacity: 1;
	z-index: 1;
}

.slideshow__arrow {
	position: absolute;
	top: 0;
	bottom: 0;
	width: 50%;
	border: 0;
	padding: 0;
	margin: 0;
	background: none;
	cursor: pointer;
	z-index: 3;
	opacity: 0;
	transition: opacity 150ms ease-in-out;
	display: flex;
	align-items: center;
}

.slideshow__arrow--prev { left: 0;  justify-content: flex-start; }
.slideshow__arrow--next { right: 0; justify-content: flex-end;   }

.slideshow:hover .slideshow__arrow { opacity: 1; }

.slideshow__arrow svg {
	width: 36px;
	height: 36px;
	margin: 0 10px;
	overflow: visible;
}

.slideshow__arrow .arrow-inner {
	fill: none;
	stroke: rgba(0, 0, 0, 0.85);
	stroke-width: 1.5px;
	stroke-linecap: square;
}

.slideshow__arrow .arrow-outer {
	fill: none;
	stroke: #000;
	stroke-width: 2.5px;
	stroke-linecap: square;
	opacity: 0;
}

.slideshow__caption {
	margin-top: 0.6em;
	margin-bottom: 0.5rem;
	font-family: "TeX Gyre Heros Condensed", Icons, sans-serif;
	font-size: var(--small-size);
	font-style: normal;
	font-weight: 400;
	line-height: 1.3;
	letter-spacing: 0.07em;
	text-align: left;
	color: rgba(0, 0, 0, 0.75);
}

/* Touch devices have no hover, so keep the arrows out of the way entirely. */
@media (hover: none) {
	.slideshow__arrow { display: none; }
}


/* --------------------------------------------------------------------------
   8. Backdrops
   --------------------------------------------------------------------------
   A backdrop sits behind the page content and fills the viewport.
   Two kinds are in use:
     .backdrop--wallpaper  a still image, cover-scaled (Mondograph)
     .backdrop--slitscan   the animated WebGL effect (home page)
   -------------------------------------------------------------------------- */

.backdrop {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 1;
	width: 100%;
	height: 100%;
	max-height: 100vh;
	overflow: hidden;
}

.backdrop--wallpaper {
	background-position: center center;
	background-repeat: no-repeat;
	background-size: cover;
}

/* Tint laid over a wallpaper; set --backdrop-overlay to colour it. */
.backdrop--wallpaper::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--backdrop-overlay, transparent);
}

.backdrop canvas {
	display: block;
	width: 100%;
	height: 100%;
}


/* --------------------------------------------------------------------------
   9. Site menu
   -------------------------------------------------------------------------- */

#menu-button {
	position: fixed;
	top: 2rem;
	right: 1.5rem;
	z-index: 9;

	display: block;
	padding: 1px;
	background: rgba(33, 32, 46, 0);
	color: rgba(255, 255, 0, 1);

	font-family: Icons;
	font-size: 32px;
	line-height: 0.5;

	text-decoration: none;
	cursor: pointer;
	box-sizing: content-box;
	pointer-events: auto;
}

#menu-button.is-open { display: none; }

#menu-panel {
	display: none;
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 10;
	cursor: default;
}

#menu-panel.is-open { display: block; }

#menu {
	pointer-events: auto;
	position: absolute;
	top: 0;
	bottom: 0;
	right: 0;                       /* menu is anchored top-right */
	z-index: 11;

	display: flex;
	flex-direction: column;
	justify-content: flex-start;

	min-width: 400px;
	max-width: 800px;
	padding: 20px 30px 90px 30px;

	background: rgba(20, 20, 20, 0.95);
	font-family: "Space Grotesk", Icons, sans-serif;
	font-size: 25px;
	font-style: normal;
	font-weight: 400;
	line-height: 0;
	text-align: left;

	overflow-x: hidden;
	overflow-y: auto;
}

#menu div { display: block; }

#menu a {
	display: inline-block;
	max-width: 100%;
	line-height: 1.4;
	color: rgba(255, 255, 255, 0.95);
	text-decoration: none;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

#menu a:active      { opacity: 0.7; }
#menu a.is-current  { opacity: 0.4; }

#menu .menu-break  { height: 28px; }
#menu .menu-indent { margin-left: 28px; }

#menu .menu-close {
	display: none;                  /* shown on mobile only */
	position: absolute;
	top: 0;
	right: 10px;
	color: rgba(255, 255, 255, 0.4);
	font-size: 45px;
	line-height: 0.88em;
	font-weight: 200;
	cursor: pointer;
	user-select: none;
}


/* --------------------------------------------------------------------------
   10. Mobile
   --------------------------------------------------------------------------
   The .is-mobile class is added to <body> by site.js when the viewport is
   narrower than 770px — the same breakpoint the original used. It is a class
   rather than a media query because the JavaScript that sizes the root font
   needs to agree with it exactly.
   -------------------------------------------------------------------------- */

.is-mobile .page-container {
	--content-width: 100%;          /* pages go full width  */
	--page-min-height: 10px;
}

.is-mobile .page-body { padding: var(--page-padding-mobile); }

/* Stacking: only rows marked grid-responsive collapse to one column. */
.is-mobile [grid-responsive] [grid-col] {
	width: 100%;
	flex: none;
}

.is-mobile #menu-button {
	margin: -6px;
	font-size: 35px;
	line-height: 0.5;
	top: 1.1rem;
	right: 1rem;
}

.is-mobile #menu {
	width: 100%;
	min-width: auto;
	max-width: 100%;
	padding: 20px;
	line-height: 1.2;
}

.is-mobile #menu .menu-close {
	display: block;
	font-size: 50px;
	line-height: 1em;
}

/* The fixed header must not cover a short mobile page. */
.is-mobile .pin--top > .page-container { --page-min-height: 0; }

/* The Previous / Next bar was desktop-only on the original. */
.is-mobile .project-nav { display: none; }
