/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */



/* Allow light/dark color scheme auto-switching via prefers-color-scheme */
.color-scheme-light-dark {
  color-scheme: light dark;
}

html {
  scroll-behavior: smooth;
}

/* iOS Safe Area Support */
.safe-area-top {
  padding-top: env(safe-area-inset-top);
}

.safe-area-bottom {
  padding-bottom: env(safe-area-inset-bottom);
}

.modal-backdrop {
  /* Full screen coverage for modal backdrop - covers everything including safe areas */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  /* No padding - let it cover the entire screen including notch/status bar */
}

/* Watermark Overlay */
.watermark-overlay {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  z-index: 10;
}

.watermark-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-30deg);
  white-space: nowrap;
  font-size: clamp(1rem, 5vw, 2.5rem);
  font-weight: 700;
  color: rgba(255, 255, 255, 0.35);
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

/* For dark images, use a slightly brighter watermark */
.watermark-overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.05);
  pointer-events: none;
}

/* ========================================
   Work Gallery
   ======================================== */

.work-gallery-scroll {
  -webkit-overflow-scrolling: touch;
}

/* Prevent text selection during lightbox interaction */
[data-controller="work-lightbox"] {
  user-select: none;
}

/* Gallery slide transition for lightbox */
[data-work-lightbox-target="slide"] {
  will-change: opacity;
}

/* ========================================
   Article Gallery (inline, full-bleed)
   ======================================== */

/* Break an embedded gallery out of the narrow article reading column so it
   spans wider than the text, centered on the column's center line and capped
   so it never dominates the page. Safe because no ancestor in the rendered
   article body clips horizontally, and the article page wrapper carries
   `overflow-x: clip` to absorb the sub-pixel overflow that 100vw produces.
   (overflow-x: clip, not hidden — clip does not establish a scroll container
   and does not affect overflow-y, and it does not reposition fixed elements
   like the lightbox.) */
.article-body .article-bleed {
  width: 100vw;
  max-width: 1200px;
  margin-inline: calc(50% - min(50vw, 600px));
}

/* ========================================
   Lexxy editor — custom attachment layout + persistent delete button
   ========================================
   Lexxy renders custom attachments (our work/gallery embeds) as
   <action-text-attachment> custom elements, which default to display:inline
   and are NOT a positioning context. Two problems follow:
     1. The inline element wrapping a block-level preview card produces
        bizarre layout (the card doesn't behave as its own line).
     2. Each attachment's delete button is position:absolute, so with no
        positioned ancestor they ALL anchor to the editor content container
        and stack at the top of the editor.
   Force the attachments block + relative so each renders on its own line and
   its delete button anchors to it. Visual-only CSS; Lexical's JS model
   (isInline) and exportDOM serialization are unaffected. */
lexxy-editor action-text-attachment {
  display: block;
  position: relative;
  /* A single controlled gap before/after the embed — replaces the stack of
     figure UA margins + my-4 that left a huge gap to the next paragraph. */
  margin-block: 0.75rem;
}

/* Lexxy hides each attachment's delete button (opacity:0) until the
   attachment is selected (.node--selected) — poor discoverability for
   embedded works. Force it visible + clickable, anchored top-right of the
   attachment (which is now position:relative above). The !important wins
   over Lexxy's :where()-wrapped rule. */
lexxy-editor lexxy-node-delete-button {
  opacity: 1 !important;
  pointer-events: auto !important;
  inset-block-start: 6px !important;
  inset-inline-start: auto !important;
  inset-inline-end: 6px !important;
}

/* Editor attachment previews: the <figure> inside our embed cards was
   stacking margins (browser UA figure margin + the preview's my-4 + the empty
   <p> we append after insert), leaving a huge gap before the next paragraph.
   Zero the figure's own margins and let the attachment element's block layout
   provide the only spacing. Selector is scoped to lexxy-editor so it can't
   affect the published .article-body figure styling.

   white-space: normal overrides the `pre-wrap` Lexical sets inline on
   .lexxy-editor__content. pre-wrap makes every newline/indent in our preview
   HTML render as a real line break — the phantom gap. `normal` collapses
   that whitespace to a single space (standard HTML behavior) for embed
   previews only; Lexical's text-editing behavior in the editable root is
   untouched. */
lexxy-editor action-text-attachment figure {
  margin: 0 !important;
  white-space: normal !important;
}

/* ========================================
   Article Body — editorial typography
   ========================================
   Long-form reading column, hand-written (no @tailwindcss/typography
   dependency: this app is importmap-based with no npm, so the plugin can't be
   installed without adding build machinery — Core Belief no. 1). Gives full
   control of the editorial look.

   Constrained measure (~42rem) centered in the page for comfortable reading;
   because the column is centered, full-bleed gallery embeds (.article-bleed)
   still break out to the viewport by contrast.

   Serif via a high-quality system stack — zero assets, no CDN, no FOUT, more
   reliable than self-hosting (matches the intent of the Geist self-hosting
   stance). Self-host a specific serif (Source Serif 4 / Newsreader) later if
   cross-platform pixel-consistency is wanted. */

.article-body {
  max-width: 42rem;
  margin-inline: auto;
  font-family: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Charter, Georgia, "Times New Roman", serif;
  font-size: 1.1875rem;        /* 19px — a clear, comfortable bump from 16px */
  line-height: 1.75;
  color: var(--color-zinc-800);
}

@media (prefers-color-scheme: dark) {
  .article-body { color: var(--color-neutral-200); }
}

.article-body > :first-child { margin-top: 0; }
.article-body > :last-child { margin-bottom: 0; }

/* Generous spacing between paragraphs (explicitly requested). */
.article-body p { margin-block: 1.4em; }

.article-body h1,
.article-body h2,
.article-body h3,
.article-body h4 {
  font-family: inherit;          /* serif headings: the piece speaks one voice */
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin-top: 2em;
  margin-bottom: 0.6em;
}
.article-body h1 { font-size: 2rem; }
.article-body h2 { font-size: 1.625rem; }
.article-body h3 { font-size: 1.3125rem; }
.article-body h4 { font-size: 1.125rem; }

.article-body a {
  color: var(--color-blue-700);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.article-body a:hover { color: var(--color-blue-800); }

@media (prefers-color-scheme: dark) {
  .article-body a { color: var(--color-blue-300); }
  .article-body a:hover { color: var(--color-blue-200); }
}

.article-body strong { font-weight: 600; }
.article-body em { font-style: italic; }

.article-body ul,
.article-body ol {
  margin-block: 1.4em;
  padding-left: 1.5em;
}
.article-body ul { list-style: disc; }
.article-body ol { list-style: decimal; }
.article-body li { margin-block: 0.4em; }
.article-body li::marker { color: var(--color-zinc-400); }

.article-body blockquote {
  margin-block: 1.6em;
  padding-left: 1.25rem;
  border-left: 3px solid var(--color-zinc-300);
  font-style: italic;
  color: var(--color-zinc-600);
}

.article-body code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--color-zinc-100);
  padding: 0.1em 0.35em;
  border-radius: 0.25rem;
}
.article-body pre {
  font-family: var(--font-mono);
  margin-block: 1.6em;
  padding: 1rem 1.25rem;
  background: var(--color-zinc-50);
  border: 1px solid var(--color-zinc-200);
  border-radius: 0.5rem;
  overflow-x: auto;
  font-size: 0.95rem;
  line-height: 1.6;
}
.article-body pre code { background: none; padding: 0; }

/* Inline images pasted directly into the prose get breathing room.
   Excludes images inside an .article-embed (the filmstrip), which would
   otherwise inherit this margin and stack excess space beneath each image. */
.article-body img:not(.article-embed img) { margin-block: 1.6em; }

/* ========================================
   Article Embed Caption
   ========================================
   The attribution under an embedded work: the work's title as a quiet
   italic label (not a link), with a subtle "view work →" action below it.

   Scoped under .article-body to win specificity over the body's link
   styling (.article-body a = 0,1,1; these = 0,2,0) so the title never goes
   link-blue and the action stays muted instead of underlined. */

.article-body .article-embed-caption {
  margin-top: 1.5rem;
  text-align: center;
}

.article-body .article-embed-title {
  font-family: inherit;            /* serif, from .article-body */
  font-style: italic;              /* editorial convention for artwork titles */
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.4;
  color: var(--color-zinc-600);
  margin: 0 0 0.25rem;
}

.article-body .article-embed-action {
  display: inline-block;
  font-family: var(--font-sans);   /* sans, to contrast the serif body */
  font-size: 0.8rem;
  color: var(--color-zinc-400);
  text-decoration: none;
  transition: color 0.2s ease;
}
.article-body .article-embed-action:hover { color: var(--color-zinc-700); }

@media (prefers-color-scheme: dark) {
  .article-body .article-embed-title { color: var(--color-neutral-400); }
  .article-body .article-embed-action { color: var(--color-neutral-500); }
  .article-body .article-embed-action:hover { color: var(--color-neutral-300); }
}

@media (prefers-color-scheme: dark) {
  .article-body li::marker { color: var(--color-neutral-600); }
  .article-body blockquote {
    border-left-color: var(--color-neutral-700);
    color: var(--color-neutral-400);
  }
  .article-body code { background: var(--color-neutral-900); }
  .article-body pre {
    background: var(--color-neutral-950);
    border-color: var(--color-neutral-800);
  }
}