/* Main CSS */

@import 'normalize.css';
@import 'typography.css';
@import 'ui.css';

/* Enable cross-document View Transitions for same-origin navigations.
   Browsers that don't support this (older Firefox etc.) simply navigate normally. */
@view-transition {
  navigation: auto;
}

/* Tune the default cross-fade so the new content feels graceful, not abrupt.
   Named elements (left-column, footer, hero-image) animate independently. */
::view-transition-group(root) {
  animation-duration: 280ms;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 220ms;
  animation-timing-function: ease;
}

/* Base layout */
html {
  scrollbar-gutter: stable;
}

@supports not (scrollbar-gutter: stable) {
  html {
    overflow-y: scroll;
  }
}

html,
body {
  overscroll-behavior-y: none;
}

body {
  background-color: var(--color-background);
  padding: 0;
  margin: 0;
  color: var(--color-text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.container {
  max-width: 650px; /* Reverted to original width */
  margin: 0;
  padding: 0 var(--space-lg); /* Side padding for smaller viewports */
}

/* ==========================================================================
   Page grid

   Six columns, 16px gutters, 16px margins. The designs are drawn 1440 wide,
   and that is where the grid stops growing: past it the page sits in the
   middle instead of stretching a note into lines too long to read.

   Every page is the same grid and places its own pieces on it:
     index   name in 2; intro, filters and posts in 3–5; About's hover preview in 2
     note    ← Index over ↑ Previous / ↓ Next in 2; meta, title, body in 3–5
     about   ← Index over the photo in 2; text in 3–5

   Under 1180 the columns get too narrow for that, so tablets move everything
   out a column (the rail into 1, content from 2); phones drop to four
   columns and stack. Both are at the end of this section.
   ========================================================================== */

:root {
  --grid-columns: 6;
  --grid-gutter: 16px;
  --grid-margin: 16px;
  --grid-max-width: 1440px;
  --page-top: 168px;
}

.page-grid {
  position: relative; /* The index's hover preview is placed against it */
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  width: 100%;
  max-width: var(--grid-max-width);
  margin: 0 auto;
  padding: var(--page-top) var(--grid-margin) var(--space-xl);
  box-sizing: border-box;
  flex: 1; /* Fill body so footer can sit at the bottom on short pages */
}

.left-column {
  align-self: start; /* Required for sticky positioning in a grid */
  text-align: left;
  view-transition-name: left-column; /* Persist visually across page navigations */
}

/* Stretches down its row, so the footer inside it sits at the bottom. */
.right-column {
  min-width: 0;
  animation: fadeIn 0.5s ease-in-out;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/* --- Index --- */

.index-layout > .left-column {
  grid-column: 2;
  position: -webkit-sticky;
  position: sticky;
  top: var(--page-top); /* Stays where it starts, like the nav on a note */
}

/* --tile-columns is how many tiles the Images view fits across. */
.index-layout > .right-column {
  grid-column: 3 / 6;
  --tile-columns: 3;
}

/* --- Note --- */

/* The masthead and the nav share the top row; the body takes the rest, so
   the nav can stay put beside it the whole way down. */
.note-layout {
  grid-template-rows: auto 1fr;
}

.note-layout > .left-column {
  grid-column: 2;
  grid-row: 1 / 3;
  position: -webkit-sticky;
  position: sticky;
  top: var(--page-top); /* Stays exactly where it starts, from scroll = 0 */
}

/* The masthead starts level with ← Index. */
.note-layout > .content-header-container.note {
  grid-column: 3 / 6;
  grid-row: 1;
}

.note-layout > .right-column {
  grid-column: 3 / 6;
  grid-row: 2;
}

/* --- About --- */

.about-layout > .left-column {
  grid-column: 2;
}

.about-layout > .right-column {
  grid-column: 3 / 6;
}

/* --- Tablet: the rail in column 1, content from 2 --- */
@media (max-width: 1179px) {
  .index-layout > .left-column,
  .note-layout > .left-column,
  .about-layout > .left-column {
    grid-column: 1;
  }

  .index-layout > .right-column,
  .note-layout > .content-header-container.note,
  .note-layout > .right-column,
  .about-layout > .right-column {
    grid-column: 2 / -1;
  }

  /* Five columns runs text wider than it is at 1440; hold it to that. */
  .index-layout .intro,
  .note-header,
  .note-content-body,
  .about-content {
    max-width: 696px;
  }
}

/* --- Phones: four columns, everything stacked --- */
@media (max-width: 699px) {
  :root {
    --grid-columns: 4;
    --page-top: var(--space-xl);
  }

  .index-layout > .left-column,
  .index-layout > .right-column,
  .note-layout > .left-column,
  .note-layout > .content-header-container.note,
  .note-layout > .right-column,
  .about-layout > .left-column,
  .about-layout > .right-column {
    grid-column: 1 / -1;
  }

  .index-layout > .left-column {
    margin-bottom: var(--space-md);
  }

  .index-layout > .right-column {
    --tile-columns: 2;
  }

  /* Nav, then masthead, then body. */
  .note-layout {
    grid-template-rows: auto auto 1fr;
  }

  .note-layout > .left-column {
    grid-row: 1;
    position: static; /* Disable sticky positioning */
    margin-bottom: var(--space-lg);
  }

  .note-layout > .content-header-container.note { grid-row: 2; }
  .note-layout > .right-column { grid-row: 3; }

  .about-layout > .left-column {
    margin-bottom: var(--space-lg);
  }
}

header {
  padding-top: 0;
  padding-bottom: 0;
  margin-bottom: 0;
}



/* Navigation styles */

.header-nav {
  display: flex;
  gap: var(--space-md);
  font-size: 0.875rem;
}

.site-header {
  transition: margin-top 0.3s ease-in-out, font-size 0.3s ease-in-out;
}

/* On a note, one column: ← Index, then ↑ Previous / ↓ Next 40px below it,
   with the filter they walk inside (when there is one) at the top of that
   pair. */
.left-column .note-nav-group {
  margin-top: 40px;
}

.left-column .note-nav-filter {
  margin-bottom: var(--space-xs);
}

.left-column .site-nav {
  position: relative;
}

.left-column .note-nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs); /* 8px - keeps Previous and Next tight as a unit */
}

/* On a tablet the rail is one narrow column; a long filter name wraps there
   rather than running into the text beside it. */
@media (min-width: 700px) and (max-width: 1179px) {
  .left-column .nav-filter-link {
    white-space: normal;
  }
}

/* A phone has the nav above the masthead rather than beside it, so the two
   halves sit side by side to keep the title near the top. */
@media (max-width: 699px) {
  .note-layout .site-header {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--grid-gutter);
  }

  .left-column .note-nav-group {
    margin-top: 0;
  }
}

.left-column .nav-filter-link {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  color: var(--font-style-body-secondary-color);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  white-space: nowrap;
  position: relative;
}

/* The label underlines on hover, never the glyph beside it. */
.left-column .nav-filter-link:hover {
  text-decoration: none;
}

.left-column .nav-filter-link:hover .nav-label {
  text-decoration: underline;
}

/* Custom instant hover tooltip for filter indicator */
.left-column .nav-tooltip {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  background-color: var(--color-text);
  color: var(--color-background);
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  line-height: 1.3;
  padding: 3px 8px;
  border-radius: 4px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 20;
  opacity: 0;
  visibility: hidden;
  text-decoration: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  transition: opacity 0.15s ease, visibility 0.15s ease;
}

.left-column .nav-tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 4px;
  border-width: 4px;
  border-style: solid;
  border-color: var(--color-text) transparent transparent transparent;
}

/* Show tooltip immediately on hover without delay */
.left-column .nav-filter-link:hover .nav-tooltip,
.left-column .nav-filter-link:focus-visible .nav-tooltip {
  opacity: 1;
  visibility: visible;
  transition: none;
}

.next-note-title {
  display: block;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
  margin-top: var(--space-xs);
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
}

.left-column .site-nav:hover .next-note-title {
  visibility: visible;
  opacity: 1;
}

/* Standalone links in the secondary ink, like the filter row on the index. */
.left-column .back-link-title a,
.left-column .read-newer-link,
.left-column .read-older-link {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.left-column .nav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem; /* 16px - uniform icon slot centering arrow and cross glyphs */
  flex-shrink: 0;
  line-height: 1;
  text-decoration: none;
}

.left-column .nav-label {
  display: inline-block;
  line-height: inherit;
}

.left-column .back-link-title a:hover,
.left-column .read-newer-link:hover,
.left-column .read-older-link:hover {
  text-decoration: none;
}

.left-column .back-link-title a:hover .nav-label,
.left-column .read-newer-link:hover .nav-label,
.left-column .read-older-link:hover .nav-label {
  text-decoration: underline;
}

/* A photography note's View as (components.js), as far under Previous /
   Next as they are under ← Index: "View as", then 8px under it three 24px
   Material Symbols 4px apart, in the weight the viewer's Close is set in.
   The view in use is in the text's own ink with a 3px dot 2px under it; the
   others are in the tertiary grey, and darken under the pointer. */
.left-column .gallery-layout-nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs);
  margin-top: 40px;
}

.left-column .gallery-layout-label {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
}

.left-column .gallery-layout-buttons {
  display: flex;
  gap: 4px;
  padding-bottom: 5px; /* Room for the dot */
}

.left-column .gallery-layout-button {
  position: relative;
  display: block;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-text-tertiary);
  cursor: pointer;
}

.left-column .gallery-layout-button .material-symbols-outlined {
  display: block;
  font-family: 'Material Symbols Outlined';
  font-size: 24px;
  font-weight: 200;
  line-height: 1;
  font-variation-settings: 'FILL' 0, 'wght' 200, 'GRAD' 0, 'opsz' 24;
}

.left-column .gallery-layout-button:hover,
.left-column .gallery-layout-button[aria-pressed="true"] {
  color: var(--color-text);
}

.left-column .gallery-layout-button[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  top: 26px;
  left: 50%;
  width: 3px;
  height: 3px;
  margin-left: -1.5px;
  border-radius: 50%;
  background-color: currentColor;
}

.left-column .gallery-layout-button:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* A phone has ← Index and Previous / Next side by side; View as goes on the
   line under them. */
@media (max-width: 699px) {
  .left-column .gallery-layout-nav {
    grid-column: 1 / -1;
    margin-top: var(--space-md);
  }
}

.header-nav a {
  color: var(--color-text-light)  !important;
  text-decoration: none;

}

.header-nav a:hover,
.header-nav a.active {
  text-decoration: underline;
  color: var(--color-text);
}

/* An h1 by markup, body copy by eye: it needs the body's line box, or the
   name and ← Index sit a couple of pixels above the text beside them. */
.site-title {
  font-family: var(--font-style-title-family);
  font-size: var(--font-style-title-size);
  font-weight: var(--font-style-title-weight);
  line-height: var(--font-style-body-primary-line-height);
  color: var(--font-style-title-color);
  margin-bottom: 0;
  white-space: nowrap;
  transition: font-size 0.3s ease-in-out, margin 0.3s ease-in-out;
}

.index-layout .site-title {
  font-weight: var(--font-style-title-weight-bold);
}

.site-title a {
  color: var(--color-text);
  text-decoration: none;
}

.site-title a:hover {
  text-decoration: underline;
}

main {
  padding: 0;
  flex-grow: 1;
}

footer {
  padding: var(--space-lg) 0 var(--space-sm) 0;
  view-transition-name: site-footer; /* Persist visually across page navigations */
}

.footer-container {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: var(--space-lg);
}

.copyright {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
}

.footer-container a {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  text-decoration: none;
}

.footer-container a:hover {
  text-decoration: underline;
}

section {
  margin-bottom: var(--space-xxxl); /* 128px, New layout spacing */
  padding-bottom: 0; /* New layout, margin handles inter-section space */
  /* border-bottom: 1px solid var(--color-border); */ /* Removed as per request */
}

/* ==========================================================================
   Intro
   ========================================================================== */

.intro p {
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  color: var(--font-style-body-primary-color);
  margin-bottom: var(--space-md); /* A blank line, on the 8px grid */
}

/* "More about me [or not]": two links in the secondary ink (see the link
   rules in typography.css). */
.intro .intro-links {
  margin-top: var(--space-md);
  margin-bottom: 0;
  color: var(--font-style-body-secondary-color);
}

.intro {
  margin-bottom: 56px; /* To the filter row */
  padding-bottom: 0;
}

.view-all {
  color: var(--color-text);
  text-decoration: none;
}

.view-all:hover {
  text-decoration: underline;
}

/* Ensure .view-all link within these sections has correct top margin */
.notes-section > .view-all {
  display: inline-block;
  margin-top: var(--space-sm); /* M (40px), New layout spacing */
}


/* --- Filters and the view toggle --- */

/* Words / Images, with the topics on the line under them. */
.index-toolbar {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs);
  margin-bottom: var(--space-md); /* 24px to the first post */
}

.view-switch {
  display: flex;
  gap: var(--space-sm);
}

/* One line under Words / Images on what the view you are in shows. */
.view-description {
  margin: 0;
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  line-height: var(--font-style-body-primary-line-height);
  color: var(--font-style-body-secondary-color);
}

.tag-filter-container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.tag-filter-container[hidden] {
  display: none; /* Filtering turned off in posts.js */
}

.tag-filter {
  font-weight: var(--font-style-body-primary-weight);
  font-size: var(--font-style-body-primary-size);
  color: var(--font-style-body-secondary-color);
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  user-select: none;
}

.tag-filter:hover {
  text-decoration: underline;
}

.tag-filter.selected {
  color: var(--font-style-body-primary-color);
  font-weight: var(--font-style-title-weight-bold);
}

/* Words / Images: the same look as the topics, the one you are in in
   brackets. */
.view-option {
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: var(--font-style-body-secondary-color);
  cursor: pointer;
}

.view-option:hover {
  text-decoration: underline;
}

.view-option.selected {
  color: var(--font-style-body-primary-color);
  font-weight: var(--font-style-title-weight-bold);
  cursor: default;
  text-decoration: none;
}

.view-option:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* ==========================================================================
   Notes List
   ========================================================================== */


.notes-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* Make entire list items clickable */
.note-link-wrapper {
  display: block;
  text-decoration: none;
  color: inherit;
}

.note-link-wrapper:hover {
  text-decoration: none; /* Remove underline from the link wrapper */
}

.note-link-wrapper:hover .article-title {
  text-decoration: underline; /* Apply underline only to the title */
}


/* The hover preview for a note in Words and for "More about me": over the
   page, just above or below what is hovered. home-notes.js sets where and
   how big, from the image. */
#note-preview {
  position: absolute;
  z-index: 10;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease-in-out;
}

#note-preview.visible {
  opacity: 1;
}

#note-preview img {
  display: block;
  width: 100%;
  height: 100%;
}

@media (prefers-reduced-motion: reduce) {
  #note-preview {
    transition: none;
  }
}

/* Nothing to hover with, or no room beside the posts. */
@media (hover: none), (max-width: 699px) {
  #note-preview {
    display: none !important;
  }
}



/* Restore note item styles */

.note-item {
  margin-bottom: var(--space-sm); /* 16px between rows */
  position: relative;
}

.note-item.has-description {
  margin-bottom: var(--space-sm);
}

/* The date, then the title a fixed 80px along from it. */
.note-item-content {
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr);
  align-items: baseline;
}

.note-item-content .note-text-content {
  grid-column: 2;
  min-width: 0;
}

.note-item-content .article-title {
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  color: var(--font-style-body-primary-color);
  line-height: inherit;
  margin: 0;
}

.note-item-content .article-description {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  margin: 2px 0 0 0;
  line-height: 1.5;
  text-decoration: none;
}

.note-link-wrapper:hover .article-description {
  text-decoration: none;
}

/* A locked post's padlock: Material Symbols' "lock", or "lock_open_right"
   while the password's session is going (js/icon-utils.js). An 18px box in
   the title's own ink, the middle of the lock on the middle of the title's
   capitals.

   Worked out from the two fonts, since neither lines up by itself. The
   title's capitals are 0.673em of Newsreader, so their middle is 0.3365 of
   the title's size above the baseline (5.7px at 17px). The lock's ink runs
   from 0.121em to 0.908em above its own baseline, which falls on the bottom
   of its box; its middle is 0.515em up, 9.26px at 18px. So the box's bottom
   drops 9.26px below the capitals' middle. Written from the title's size
   rather than with em or cap, which here would measure the icon's font.
   Weight 300 at the 20px optical size gives the hairline of the text beside
   it. */
.lock-icon {
  display: inline-block;
  width: 18px;
  height: 18px;
  margin-left: 4px;
  overflow: hidden; /* The name, before the font arrives, stays out of sight */
  vertical-align: calc(var(--font-style-title-size) * 0.3365 - 9.26px);
  font-family: 'Material Symbols Outlined';
  font-size: 18px;
  font-weight: 300;
  font-style: normal;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  font-feature-settings: 'liga';
  font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 20;
}

/* Off-site posts open in a new tab; the arrow says so before the click. */
.external-mark {
  color: var(--color-text-tertiary);
}


/* Date styling */

.note-item-content .note-date {
  grid-column: 1;
  margin: 0;
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  text-align: left;
}


/* ==========================================================================
   Images view

   The pictures and videos the notes mark with data-home (data/media.json),
   in full rows, as a gallery note's photographs are, each whole and hung
   from the top of its row. Hovering one swaps the
   picture for its date and title; clicking one opens the enlarged view.
   ========================================================================== */

/*
 * Rows, as .gallery-row in notes.css has them: every row runs the full
 * width, as one tile across, a wide and a narrow one, or three across. The
 * tallest picture in a row sets its height; the others hang from its top,
 * with space below them.
 *
 * Which tiles share a row, and at what widths, is home-notes.js's to say
 * (layoutTiles): it places every tile by column and row, and keeps the
 * order in step with the notes.
 */
.index-tiles {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(var(--tile-columns, 3), minmax(0, 1fr));
  gap: var(--grid-gutter);
  align-items: start;
}

.index-tile__link {
  position: relative;
  display: block;
  text-decoration: none;
  color: inherit;
}

.index-tile__link:hover {
  text-decoration: none;
}

.index-tile__link:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

.index-tile__media {
  display: block;
  transition: opacity 0.2s ease;
}

/* The full width of its columns, at the picture's own height. Never cropped,
   never squeezed. The box has that shape already (home-notes.js sets it from
   media.json), so until the picture arrives it is a grey block the size it
   will be, and nothing jumps as the pictures load. */
.index-tile__media {
  background-color: var(--color-placeholder);
  /* A hairline, drawn inside the edge so the box keeps the size the mosaic
     placed it at. An outline, as a border would add to it and an inset
     shadow would sit under the picture. */
  outline: 1px solid var(--color-tile-border);
  outline-offset: -1px;
}

.index-tile__media img,
.index-tile__media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover; /* Only ever covers rounding: the box has its shape */
}

/* A stack: the rest of it as edges behind the first item, each 2px further
   down and to the right, as in the designs. */
.media-tile .index-tile__link {
  isolation: isolate; /* Keeps the edges behind this tile, not the page */
}

.media-tile__layer {
  position: absolute;
  inset: 0;
  z-index: -1;
  box-sizing: border-box;
  background-color: var(--color-background);
  border: 1px solid var(--color-placeholder);
  transform: translate(calc(var(--layer) * 2px), calc(var(--layer) * 2px));
}

/* Laid over the picture, 12px in from every edge of it: off the 8px grid,
   on purpose, to sit tighter in the corner. */
.index-tile__caption {
  position: absolute;
  inset: 0;
  padding: 12px;
  box-sizing: border-box;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.index-tile__date {
  color: var(--font-style-body-secondary-color);
}

.index-tile__title {
  max-width: 75%;
  color: var(--font-style-body-primary-color);
}

.index-tile__link:hover .index-tile__media,
.index-tile__link:focus-visible .index-tile__media {
  opacity: 0;
}

.index-tile__link:hover .index-tile__caption,
.index-tile__link:focus-visible .index-tile__caption {
  opacity: 1;
}

/* Under the pointer: the date, and the title underlined like one in the list. */
.index-tile__link:hover .index-tile__title {
  text-decoration: underline;
}

/* A title longer than its tile has room for stops at the last line that
   fits, with an ellipsis. home-notes.js (fitTileTitles) counts the lines. */
.index-tile__title.is-clamped {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--title-lines);
  overflow: hidden;
  flex: none;
}

/* The whole of a clamped title, while the pointer is on its words: the
   Clear filter tooltip again, but wrapping, since titles run long. It sits
   on the body, where no tile can clip or cover it, and home-notes.js
   places it above the title, or below when the window has no room. */
.tile-tooltip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 20;
  box-sizing: border-box;
  width: max-content;
  max-width: min(320px, 100vw - 32px);
  padding: 3px 8px;
  border-radius: 4px;
  background-color: var(--color-text);
  color: var(--color-background);
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  line-height: 1.3;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, visibility 0.15s ease;
}

/* Pointing down at the title's first letter... */
.tile-tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: var(--arrow-x, 4px);
  border-width: 4px;
  border-style: solid;
  border-color: var(--color-text) transparent transparent transparent;
}

/* ...or up at it, from below. */
.tile-tooltip.is-below::after {
  top: auto;
  bottom: 100%;
  border-color: transparent transparent var(--color-text) transparent;
}

/* Straight away, as the Clear filter one does. */
.tile-tooltip.is-visible {
  opacity: 1;
  visibility: visible;
  transition: none;
}

/* Without hover there is nothing to swap, and the picture is the point.
   A tap opens the enlarged view, where the title and context are. */
@media (hover: none) {
  .index-tile__caption {
    display: none;
  }

  .index-tile__link:hover .index-tile__media {
    opacity: 1;
  }
}

/* ==========================================================================
   Enlarged view (js/media-viewer.js)

   Over the whole window, on the page grid: Close in column 2 with the date
   and the note's title in 3–5; the current item in 2–5, the next one peeking
   in from column 6; under it, the caption in 2–4 and Read note in 5. Tablets
   move everything out a column, as the pages do; phones use the full width.
   From the index, the row runs on through every note on the wall; a
   neighbour from another note is dimmed and has that note's title under it.
   ========================================================================== */

html.media-viewer-open {
  overflow: hidden;
}

.media-viewer {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  padding: var(--space-xl) 0;
  box-sizing: border-box;
  background-color: var(--color-background);
  animation: media-viewer-in 0.2s ease;
}

.media-viewer[hidden] {
  display: none;
}

/* It takes focus itself only when opened from a pointer, so it never shows
   a ring for it. */
.media-viewer:focus {
  outline: none;
}

@keyframes media-viewer-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* The page grid again, for the lines above and below the pictures. */
.media-viewer__row {
  display: grid;
  align-items: baseline;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  width: 100%;
  max-width: var(--grid-max-width);
  margin: 0 auto;
  padding: 0 var(--grid-margin);
  box-sizing: border-box;
}

.media-viewer__close {
  grid-column: 2;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: var(--font-style-body-secondary-color);
  cursor: pointer;
}

.media-viewer__close .material-symbols-outlined {
  font-family: 'Material Symbols Outlined';
  font-size: 20px;
  font-weight: 200;
  line-height: 1;
  font-variation-settings: 'FILL' 0, 'wght' 200, 'GRAD' 0, 'opsz' 24;
}

/* The bar lines its items up on their text, and a flex box like this one
   offers the baseline of its first child, the icon, whose baseline is the
   bottom of the glyph: the date would sit on the foot of the ×. Baseline
   alignment here makes the button offer the word's baseline instead. It
   moves nothing, the word being the tallest thing in the button. */
.media-viewer__close-label {
  align-self: baseline;
}

.media-viewer__close:hover .media-viewer__close-label {
  text-decoration: underline;
}

.media-viewer__close:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* The date and the note's title, 8px apart, both in the secondary ink. The
   title is a link to the note, underlined only under the pointer. */
.media-viewer__meta {
  grid-column: 3 / 6;
  display: flex;
  gap: var(--space-xs);
  align-items: baseline;
  margin: 0;
  color: var(--font-style-body-secondary-color);
}

.media-viewer__date {
  flex: none;
}

.media-viewer .media-viewer__title {
  color: inherit !important; /* Over the site-wide link colour */
  text-decoration: none;
}

.media-viewer__title:hover {
  text-decoration: underline;
}

/* Into another note: its date and title fade in over the last one's. */
.media-viewer__meta.is-changing {
  animation: media-viewer-in 0.45s ease;
}

/* The row of pictures. media-viewer.js measures the caption below to find
   the stage (its left edge and width), sets --stage-w and --stage-h from it,
   and places every item itself: the current one at the stage, its
   neighbours one column in from the window's edges, the rest out of sight. */
.media-viewer__track {
  position: relative;
  flex: 1;
  min-height: 0;
  margin: var(--space-xl) 0;
  overflow: hidden;
  touch-action: pan-y; /* Sideways swipes are the viewer's to handle */
  user-select: none;
  -webkit-user-select: none;
}

/* As tall as the stage allows, or as wide as the room between the
   neighbours (see layout in media-viewer.js): whichever runs out first. Hung
   from the middle of the row; the transform, set in media-viewer.js, carries
   it sideways into place. */
.media-viewer__slide {
  position: absolute;
  top: 50%;
  left: 0;
  margin: 0;
  width: min(var(--stage-max-w, 100%), calc(var(--stage-h, 100%) * var(--ar)));
  transform: translate(100vw, -50%); /* Out of sight until placed */
  transition: transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.45s ease;
  will-change: transform;
  cursor: pointer;
}

/* Following a finger, or put in place on open and resize: no easing. */
.media-viewer__track.is-dragging .media-viewer__slide,
.media-viewer__track.is-instant .media-viewer__slide {
  transition: none;
}

.media-viewer__track.is-dragging {
  cursor: grabbing;
}

@media (prefers-reduced-motion: reduce) {
  .media-viewer__slide {
    transition: none;
  }
}

.media-viewer__slide.is-current {
  cursor: default;
}

/* From another note than the one in view: set back, until it is the one in
   view, or the pointer is on it. */
.media-viewer__slide.is-elsewhere {
  opacity: 0.35;
}

.media-viewer__slide.is-elsewhere:hover {
  opacity: 0.6;
}

.media-viewer__slide.is-current:has(video) {
  cursor: pointer; /* A click plays or pauses it */
}

.media-viewer__slide img,
.media-viewer__slide video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ar);
  background-color: var(--color-placeholder);
}


/* How far through the video is, under it. */
.media-viewer__progress {
  display: block;
  height: 3px;
  background-color: #dfdfdf;
  overflow: hidden;
}

.media-viewer__progress span {
  display: block;
  height: 100%;
  background-color: #111;
  transform: scaleX(0);
  transform-origin: left;
}

/* ← → on a line of their own, then "2/4  Video 2: Page turn animation" in
   2–4 and Read note in 5, both in the primary ink, the count in the
   secondary. */
.media-viewer__nav {
  grid-column: 2 / 5;
  grid-row: 1;
  display: flex;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.media-viewer__nav[hidden] {
  display: none; /* A single item: nothing to move through */
}

.media-viewer__arrow {
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: var(--font-style-body-primary-color);
  cursor: pointer;
}

.media-viewer__arrow:disabled {
  color: var(--color-text-tertiary);
  cursor: default;
}

.media-viewer__arrow:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* "Next note" over its title, under a neighbour from another note, on the
   lines the arrows and caption are on. media-viewer.js sets where and how
   wide, to the part of the neighbour in sight. Clicking it goes there. */
.media-viewer__foot {
  position: relative;
}

.media-viewer__peek {
  position: absolute;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.media-viewer__peek[hidden] {
  display: none;
}

.media-viewer__peek--prev {
  align-items: flex-end;
  text-align: right;
}

.media-viewer__peek-label {
  color: var(--font-style-body-secondary-color);
}

.media-viewer__peek-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  color: var(--font-style-body-primary-color);
}

.media-viewer__peek:hover .media-viewer__peek-title {
  text-decoration: underline;
}

.media-viewer__peek:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* The caption and Read note share the line under the arrows. The caption
   holds its line even when it is empty, so the picture above doesn't jump
   between items. */
.media-viewer__caption {
  grid-column: 2 / 5;
  grid-row: 2;
  margin: 0;
  min-height: calc(var(--font-style-body-primary-size) * var(--font-style-body-primary-line-height));
  color: var(--font-style-body-primary-color);
}

.media-viewer__count {
  margin-right: var(--space-sm);
  color: var(--font-style-body-secondary-color);
  font-variant-numeric: tabular-nums;
}

.media-viewer__more {
  grid-column: 5 / 6;
  grid-row: 2;
  margin: 0;
}

.media-viewer .media-viewer__link {
  text-decoration: none;
}

.media-viewer__link:hover {
  text-decoration: underline;
}

@media (max-width: 1179px) {
  .media-viewer__close { grid-column: 1; }
  .media-viewer__meta { grid-column: 2 / -1; }
  .media-viewer__nav,
  .media-viewer__caption { grid-column: 1 / 5; }
  .media-viewer__more { grid-column: 5 / 6; }
}

@media (max-width: 699px) {
  .media-viewer {
    padding: var(--space-md) 0;
  }

  .media-viewer__track {
    margin: var(--space-md) 0;
  }

  .media-viewer__close,
  .media-viewer__meta,
  .media-viewer__nav,
  .media-viewer__caption,
  .media-viewer__more { grid-column: 1 / -1; grid-row: auto; }

  .media-viewer__meta { margin-top: var(--space-xs); }
}


/* ==========================================================================
   Gravity
   ========================================================================== */



/* Lock scrolling when gravity is active */
html.gravity-active {
  overflow: hidden;
}

/* Change cursor for the html element and all descendants when gravity is active */
html.gravity-active,
html.gravity-active * {
  cursor: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 -960 960 960' width='24px' fill='%231f1f1f'%3e%3cpath d='M480-80q-75 0-140.5-28.5t-114-77q-48.5-48.5-77-114T120-440h80q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440q0-117-81.5-198.5T480-720h-6l62 62-56 58-160-160 160-160 56 58-62 62h6q75 0 140.5 28.5t114 77q48.5 48.5 77 114T840-440q0 75-28.5 140.5t-77 114q-48.5 48.5-114 77T480-80Z'/%3e%3c/svg%3e") 12 12, auto !important;
}

/* Disable transitions during gravity effect to prevent interference */
.gravity-active .tag-filter-button {
  transition: none !important;
}


/* ==========================================================================
   Footer
   ========================================================================== */

footer {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
}



/* Subscription section */
.subscription {
  margin: var(--space-xl) 0;
  padding: var(--space-lg) 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.subscription h2 {
  font-size: 1rem;
  font-weight: normal;
  margin-bottom: var(--space-md);
}

.subscription p {
  font-size: var(--font-style-body-primary-size);
  margin-bottom: var(--space-md);
  color: var(--color-text);
}

.subscription-form {
  display: flex;
  margin-top: var(--space-md);
}

.subscription-form input {
  flex: 1;
  padding: 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 4px 0 0 4px;
  font-size: 0.9rem;
}

.subscription-form button {
  padding: 0.5rem 1rem;
  background-color: var(--color-button-bg);
  color: var(--color-button-text);
  border: none;
  border-radius: 0 4px 4px 0;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background-color 0.2s ease;
}



/* ==========================================================================
   Content Protection
   ========================================================================== */

.content-protected {
  display: none;
}

.locked-content {
  display: none;
}

/* Password protection container */
.password-protection-container {
  max-width: 600px;
  /* No top margin: this replaces .note-content-body in the flow, so it has to
     start on the same line as unlocked body copy — and as the sticky nav. */
  margin: 0 0 var(--space-xl);
}

/* Password form */
.password-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.password-message {
  margin: 0;
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  color: var(--font-style-body-primary-color);
  text-align: left;
}

.password-input-container {
  display: flex;
  gap: 8px;
}

/* The field and the button are ui.css's Input and Button. */
.password-input {
  flex: 1;
}

.password-error {
  color: var(--error-color, #e53935);
  font-size: 0.9rem;
  text-align: left;
}

/* Access request section */
.access-request-container {
  display: flex;
  flex-direction: row;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
  padding-top: var(--space-xs);
  text-align: left;
}

.access-request-container p {
  margin: 0;
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  text-align: left;
}

.request-access-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* Access request form */
.access-request-form {
  animation: fadeIn 0.3s ease;
}

.access-request-form h3 {
  margin-top: 0;
  margin-bottom: 1rem;
  font-family: var(--font-style-h2-family);
  font-size: var(--font-style-h2-size);
  font-weight: var(--font-style-h2-weight);
  color: var(--font-style-h2-color);
}

.access-request-form p {
  margin-bottom: 1.5rem;
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}

/* Labels, fields and buttons are ui.css's Label, Input, Textarea and Button. */
.form-group .textarea {
  min-height: 100px;
}

.field-error {
  font-size: 14px;
  color: var(--error-color);
}

.form-actions {
  display: flex;
  justify-content: flex-start;
  gap: 8px;
  margin-top: 24px;
}

/* Success message */
.request-success, .request-success-final {
  text-align: left;
  padding: 1.5rem;
  animation: fadeIn 0.3s ease;
}

.request-success p, .request-success-final p {
  margin: 0;
  color: var(--success-color, #43a047);
  text-align: left;
}


/* ==========================================================================
   Responsive Design
   ========================================================================== */

   
   @media (max-width: 768px) {
    html {
      font-size: 15px;
    }
    
    .container {
      padding: 0 var(--space-sm);
    }
  }
  
  @media (max-width: 480px) {
    html {
      font-size: 14px;
    }
    
    header {
      flex-direction: column;
      align-items: flex-start;
      gap: var(--space-sm);
    }
    
    .header-nav {
      margin-top: var(--space-xs);
    }
  }

/* Animation */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
