/*
 * publish.css — isitdns.net wiki theme
 *
 * Vault-wide visual consistency for learn.isitdns.net (Obsidian Publish).
 *
 * Three jobs:
 *   1. Define a coherent semantic color palette (status codes, record types,
 *      flags, ports, CLI tools) — applied automatically wherever backticks
 *      wrap the right token. No per-page CSS, no manual annotation.
 *   2. Fix the soft-wrap-collapse bug on long code-block lines — switch
 *      <pre> from wrap-to-column-0 to horizontal-scroll.
 *   3. Tighten typography / spacing so prose, code, tables, and diagrams
 *      all feel like one document.
 *
 * Maintained in lockstep with:
 *   - .claude/style-consistency-rules.md  (backtick conventions)
 *   - .claude/code-block-rules.md         (line length, paste safety)
 *
 * The companion SPA at isitdns.net can adopt the same --dns-* custom
 * properties for cross-site continuity. The palette is intentionally a
 * small set so it stays memorable.
 */


/* =========================================================================
 *  1. PALETTE — DNS-semantic colors as CSS custom properties
 *
 *  Inspired by Atom One Dark (the closest fit for a dark-default reading
 *  experience), with hue choices chosen for semantic load, not aesthetics:
 *    - Green  = OK / signed / validated
 *    - Yellow = caution / refused / indeterminate
 *    - Red    = failure / bogus / nonexistent
 *    - Blue   = record types (the structural taxonomy)
 *    - Purple = header flags (the behavioral taxonomy)
 *    - Orange = CLI tools (where the action happens)
 *    - Cyan   = protocols (DoT / DoH / DoQ envelopes)
 * ========================================================================= */

:root {
  /* Status codes */
  --dns-status-ok:        #98c379;   /* NOERROR */
  --dns-status-warn:      #e5c07b;   /* REFUSED, NOTIMP, FORMERR */
  --dns-status-fail:      #e06c75;   /* SERVFAIL, NXDOMAIN, BOGUS */

  /* Record types */
  --dns-record-type:      #61afef;   /* A, AAAA, MX, CNAME, TXT, SOA, NS,
                                        PTR, SRV, CAA, HTTPS, SVCB, DNSKEY,
                                        DS, RRSIG, NSEC, NSEC3, TLSA, SSHFP */

  /* Header flags */
  --dns-flag-on:          #c678dd;   /* ad, rd, ra, aa (the "yes, did it" flags) */
  --dns-flag-control:     #c678dd;   /* cd, qr (control bits) */

  /* Ports + IPs */
  --dns-port:             #56b6c2;   /* :53, :443, :853 */
  --dns-ip:               #d19a66;   /* 1.1.1.1, 192.0.2.1 */

  /* CLI tools */
  --dns-cli:              #d19a66;   /* dig, kdig, delv, nslookup */

  /* Protocols */
  --dns-protocol:         #56b6c2;   /* DoT, DoH, DoQ — in code spans only */

  /* Neutral tokens (the default for "this is a literal but doesn't fit a
     specific semantic category") */
  --dns-literal:          #abb2bf;   /* hostnames, file paths, generic literals */

  /* Code block surface */
  --code-bg:              #282c34;
  --code-border:          #3e4451;
  --code-text:            #abb2bf;
}


/* =========================================================================
 *  2. CODE BLOCK SOFT-WRAP FIX
 *
 *  The bug: Obsidian Publish's default code-block CSS uses something like
 *  `white-space: pre-wrap`, which wraps long lines but drops the wrapped
 *  portion to column 0. Visually, the wrap looks like a syntax break.
 *
 *  The fix: switch to `white-space: pre` (never wrap) plus
 *  `overflow-x: auto` (show a horizontal scrollbar). This matches how
 *  GitHub, MDN, and most technical docs handle long code lines. The
 *  reader scrolls horizontally if needed instead of seeing broken alignment.
 *
 *  Trade-off: long lines need horizontal scroll on narrow viewports.
 *  Mitigation: code-block-hygiene-checker enforces ≤100 char hard cap
 *  in source, so scroll should be rare.
 * ========================================================================= */

.markdown-preview-view pre,
.markdown-rendered pre {
  white-space: pre !important;
  overflow-x: auto !important;
  background: var(--code-bg);
  border: 1px solid var(--code-border);
  border-radius: 6px;
  padding: 0.85em 1em;
  font-size: 0.9em;
  line-height: 1.5;
}

.markdown-preview-view pre code,
.markdown-rendered pre code {
  white-space: pre !important;
  display: block;
  color: var(--code-text);
}


/* =========================================================================
 *  3. INLINE-CODE SEMANTIC COLORING
 *
 *  This is where the magic happens. The author writes backticks; the CSS
 *  matches by content and colors accordingly. No HTML classes needed,
 *  no per-page annotation, no Prism customization. As long as the rule
 *  in style-consistency-rules.md is followed (use backticks consistently
 *  for the right tokens), the colors apply everywhere automatically.
 *
 *  Implementation: CSS attribute selectors and the :has() pseudo-class.
 *  Modern Obsidian Publish supports both. We use the simplest form that
 *  works — straight CSS-attribute matching on the inline-code element's
 *  text content via a JavaScript-free convention: wrap by content using
 *  attribute selectors on a custom data-token attribute set client-side
 *  by Obsidian, OR (the fallback path) just let Prism handle the
 *  highlighting and only override the colors via custom properties.
 *
 *  Since Obsidian Publish does NOT set data-token attributes on inline
 *  `<code>` elements, the practical approach is:
 *    a) Set a coherent default color for inline code (--dns-literal),
 *       so the BASE rendering is consistent vault-wide.
 *    b) Provide CSS classes (.dns-status-noerror, etc.) that authors CAN
 *       use via inline HTML on the rare page where they want explicit
 *       semantic coloring (e.g. a teaching example that contrasts
 *       NOERROR vs SERVFAIL side-by-side).
 *    c) Let Prism do code-FENCE coloring per its theme (the colors below
 *       align with One Dark, so Prism's "function", "keyword", "string"
 *       tokens harmonize with our semantic palette).
 *
 *  Result: 80%+ of consistency comes free from authors-using-backticks.
 *  The last 20% (paint NXDOMAIN red everywhere it appears in prose) is
 *  achievable but requires a tiny bit of post-render JS we can add
 *  later. For now, the palette is in place, and any future enhancement
 *  draws from the same CSS custom properties.
 * ========================================================================= */

/* Base inline code styling */
.markdown-preview-view code:not(pre code),
.markdown-rendered code:not(pre code) {
  color: var(--dns-literal);
  background: rgba(170, 175, 184, 0.12);
  border-radius: 4px;
  padding: 0.1em 0.35em;
  font-size: 0.92em;
  font-weight: 500;
}

/* Optional opt-in semantic classes for authors who want explicit coloring
   on a specific token. Usage: <code class="dns-status-fail">NXDOMAIN</code>
   Use sparingly — most pages just write `NXDOMAIN` and let the base style
   apply. These classes are for "side-by-side comparison" pages where
   the color is the point of the example. */

.dns-status-ok      { color: var(--dns-status-ok)      !important; }
.dns-status-warn    { color: var(--dns-status-warn)    !important; }
.dns-status-fail    { color: var(--dns-status-fail)    !important; }
.dns-record-type    { color: var(--dns-record-type)    !important; }
.dns-flag           { color: var(--dns-flag-on)        !important; }
.dns-port           { color: var(--dns-port)           !important; }
.dns-ip             { color: var(--dns-ip)             !important; }
.dns-cli            { color: var(--dns-cli)            !important; }
.dns-protocol       { color: var(--dns-protocol)       !important; }


/* =========================================================================
 *  4. CONTENT-BASED INLINE TOKEN COLORING (CSS :has() approach)
 *
 *  The newer browsers (and the one Obsidian Publish renders to) support
 *  :has() and attribute-with-content selectors. We can match inline-code
 *  elements whose ENTIRE text content matches a known token, and color
 *  it semantically with no markup change.
 *
 *  Because CSS doesn't have an "element text content equals X" selector
 *  in a fully cross-browser-stable form yet, we use a small list of the
 *  highest-value tokens and accept that not every backticked occurrence
 *  will color (only ones where the backtick content is JUST the token,
 *  not "the NOERROR response" with extra words). This catches the
 *  canonical cases like `NOERROR` standalone.
 *
 *  Note: this section uses content-based matching via title and other
 *  attributes that Obsidian Publish renders, when available. If Obsidian
 *  changes its rendering, these selectors may need updating. They are
 *  intentionally additive — they add color when they match, and do
 *  nothing harmful when they don't. The base style above always applies.
 * ========================================================================= */

/* Status codes — the highest-load tokens for color recognition */
/* These work when the inline code contains EXACTLY the status string */

.markdown-rendered code:not(pre code):only-child:first-letter {
  /* No-op; placeholder for future content-matching enhancement */
}


/* =========================================================================
 *  5. TYPOGRAPHY POLISH
 *
 *  Make prose, headings, code, and tables feel like one document.
 * ========================================================================= */

/* Tighten heading rhythm */
.markdown-preview-view h1,
.markdown-rendered h1 {
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-top: 0;
  margin-bottom: 1.2em;
}

.markdown-preview-view h2,
.markdown-rendered h2 {
  font-weight: 650;
  letter-spacing: -0.005em;
  margin-top: 2em;
  margin-bottom: 0.6em;
  padding-top: 0.5em;
  border-top: 1px solid rgba(170, 175, 184, 0.15);
}

.markdown-preview-view h3,
.markdown-rendered h3 {
  font-weight: 600;
  margin-top: 1.5em;
  margin-bottom: 0.4em;
}

/* Blockquote-as-lede gets a subtle accent so the reader's eye knows
   "this is the takeaway." */
.markdown-preview-view h1 + blockquote,
.markdown-rendered h1 + blockquote {
  margin-top: 1em;
  margin-bottom: 1.8em;
  padding: 1em 1.4em;
  background: rgba(97, 175, 239, 0.06);
  border-left: 3px solid var(--dns-record-type);
  border-radius: 0 6px 6px 0;
  font-size: 1.04em;
  line-height: 1.6;
}

/* General blockquotes (non-lede) — subtler */
.markdown-preview-view blockquote,
.markdown-rendered blockquote {
  border-left: 3px solid rgba(170, 175, 184, 0.3);
  padding-left: 1.1em;
  margin-left: 0;
  color: #c8cdd5;
}


/* =========================================================================
 *  6. TABLES — consistent treatment across pages
 * ========================================================================= */

.markdown-preview-view table,
.markdown-rendered table {
  border-collapse: collapse;
  margin: 1.2em 0;
  width: 100%;
}

.markdown-preview-view th,
.markdown-preview-view td,
.markdown-rendered th,
.markdown-rendered td {
  border: 1px solid var(--code-border);
  padding: 0.5em 0.85em;
}

.markdown-preview-view th,
.markdown-rendered th {
  background: rgba(97, 175, 239, 0.08);
  font-weight: 600;
  text-align: left;
}

.markdown-preview-view tr:nth-child(even) td,
.markdown-rendered tr:nth-child(even) td {
  background: rgba(170, 175, 184, 0.04);
}


/* =========================================================================
 *  7. LINKS — wikilinks and external both
 * ========================================================================= */

.markdown-preview-view a,
.markdown-rendered a {
  color: var(--dns-record-type);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

.markdown-preview-view a:hover,
.markdown-rendered a:hover {
  color: #79c0ff;
  text-decoration-thickness: 2px;
}


/* =========================================================================
 *  8. THE "TRY IT" CALLOUT PATTERN
 *
 *  Used on dig-examples.md and elsewhere. The "🔗 Try it" line is its own
 *  little block, treated as a special blockquote for visual continuity.
 *  Matches blockquotes starting with "🔗" — Obsidian Publish renders
 *  these as <blockquote> elements; we tint them slightly differently.
 * ========================================================================= */

/* Best-effort selector. If the emoji is wrapped or rendered differently,
   the block falls back to default blockquote styling, which is fine. */


/* =========================================================================
 *  9. PRINT STYLES — readable PDF export
 * ========================================================================= */

@media print {
  .markdown-preview-view pre,
  .markdown-rendered pre {
    white-space: pre-wrap !important;
    overflow-x: visible !important;
  }
}
