/* ═══════════════════════════════════════════════════════════════════════ * BREAKCORE — refined-neon layer. * Everything below is scoped to `.breakcore`; salon / salon-noir / gothic * are untouched. Aesthetic: editorial serif body in deliberate tension with * hard-edged web-rot chrome — RGB split, hazard tape, neon outline, hard * offset shadows. Motion is *reactive only* (hover / focus / one-shot on * load) and settles fast. All motion is killed by prefers-reduced-motion * at the very end of this file. * ═══════════════════════════════════════════════════════════════════════ */ /* CRT tube depth — static vignette layered on the existing base fill. */ .breakcore body::before { background-image: radial-gradient( ellipse at center, transparent 52%, color-mix(in srgb, var(--crust) 75%, transparent) 100% ); } /* Nameplate — breakcore reworks the underline: hard cyan offset + magenta * neon glow (the layer's hard-offset chrome language) instead of the * default two-tone rule. Plus a glitch-shear burst on hover. */ .breakcore .nameplate::after { height: 2px; bottom: -7px; background: var(--mauve); box-shadow: 2px 2px 0 var(--blue), 0 0 10px color-mix(in srgb, var(--mauve) 70%, transparent); } @keyframes bc-shear { 0% { clip-path: inset(0 0 0 0); transform: translateX(0); text-shadow: -1px 0 0 var(--teal), 1px 0 0 var(--mauve); } 20% { clip-path: inset(16% 0 56% 0); transform: translateX(-5px); text-shadow: -5px 0 0 var(--green), 5px 0 0 var(--mauve); } 40% { clip-path: inset(62% 0 10% 0); transform: translateX(5px); text-shadow: 5px 0 0 var(--teal), -5px 0 0 var(--red); } 60% { clip-path: inset(30% 0 42% 0); transform: translateX(-3px); text-shadow: -3px 0 0 var(--mauve), 3px 0 0 var(--green); } 80% { clip-path: inset(6% 0 78% 0); transform: translateX(2px); text-shadow: 2px 0 0 var(--teal), -2px 0 0 var(--mauve); } 100% { clip-path: inset(0 0 0 0); transform: translateX(0); text-shadow: -1px 0 0 var(--teal), 1px 0 0 var(--mauve); } } .breakcore .nameplate:hover .nameplate-title { animation: bc-shear 200ms steps(3, jump-none) 1; } /* Display headings — one-shot glitch-in on page load. The static chromatic * text-shadow (defined earlier) remains as the resting state. */ @keyframes bc-load-glitch { 0% { opacity: 0; clip-path: inset(46% 0 46% 0); transform: translateX(-9px); } 20% { opacity: 1; clip-path: inset(8% 0 70% 0); transform: translateX(7px); } 40% { clip-path: inset(68% 0 8% 0); transform: translateX(-5px); } 60% { clip-path: inset(24% 0 36% 0); transform: translateX(3px); } 80% { clip-path: inset(4% 0 84% 0); transform: translateX(-2px); } /* End unclipped (none, not inset(0)) so italic-Fraunces descenders * (g, y, p) aren't sliced at the box edge once the glitch settles. */ 100% { opacity: 1; clip-path: none; transform: translateX(0); } } .breakcore .prose h1, .breakcore h1.font-display { /* `backwards` (not `both`): after the one-shot, props revert to base — * clip-path: none — instead of persisting the final inset clip. */ animation: bc-load-glitch 460ms steps(5, jump-none) backwards; } /* Plate — hard hover (no soft lift), RGB-split image, scanline sweep. */ .breakcore .plate:hover { transform: translateY(-3px); } .breakcore .plate:hover .plate-caption-title { text-shadow: -1px 0 0 var(--teal), 1px 0 0 var(--mauve); } .breakcore .plate:hover .plate-image img { filter: drop-shadow(-3px 0 0 color-mix(in srgb, var(--mauve) 70%, transparent)) drop-shadow(3px 0 0 color-mix(in srgb, var(--teal) 70%, transparent)) saturate(1.12) contrast(1.06); } .breakcore .plate .plate-image::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: translateY(-110%); mix-blend-mode: screen; background: linear-gradient( 180deg, transparent 0%, color-mix(in srgb, var(--sky) 28%, transparent) 46%, color-mix(in srgb, var(--mauve) 70%, transparent) 49%, color-mix(in srgb, var(--green) 55%, transparent) 51%, color-mix(in srgb, var(--sky) 28%, transparent) 54%, transparent 100% ); } @keyframes bc-scan { 0% { transform: translateY(-110%); opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { transform: translateY(110%); opacity: 0; } } .breakcore .plate:hover .plate-image::after, .breakcore .plate:focus-visible .plate-image::after { animation: bc-scan 0.62s cubic-bezier(0.4, 0, 0.2, 1) 1; } /* Section rule — hazard tape. Used on footer, post header, 404. */ .breakcore .section-rule { color: var(--green); font-family: var(--font-mono); font-style: normal; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.22em; } .breakcore .section-rule::before, .breakcore .section-rule::after { height: 1px; opacity: 0.85; background: linear-gradient( to right, transparent, color-mix(in srgb, var(--mauve) 70%, transparent) 45%, color-mix(in srgb, var(--teal) 70%, transparent) 55%, transparent ); } .breakcore .section-rule .ornament { color: var(--mauve); } /* Readability — `--overlay0` (#5A2D8E) is near-invisible on the breakcore * ground. Lift the spots that use it as actual copy to the readable * subtext ramp. */ .breakcore .prose h6, .breakcore .prose del, .breakcore .hljs-comment, .breakcore .hljs-quote, .breakcore .site-copyright, .breakcore .slug-hint { color: var(--subtext0); } /* Chips — neon outline, monospace caps. */ .breakcore .chip { background: transparent; border-color: color-mix(in srgb, var(--teal) 55%, transparent); color: var(--teal); font-family: var(--font-mono); font-style: normal; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; border-radius: 0; } .breakcore .chip-accent { background: var(--mauve); color: var(--crust); border-color: var(--mauve); } .breakcore .chip-draft { background: transparent; border-color: color-mix(in srgb, var(--green) 60%, transparent); color: var(--green); } /* Plate caption meta — bracketed mono coordinates. */ .breakcore .plate-caption-meta { font-family: var(--font-mono); letter-spacing: 0.16em; } .breakcore .plate-caption-sep { color: var(--green); opacity: 1; } /* Buttons & inputs — square, hard offset block-shadow, neon focus. */ .breakcore .btn, .breakcore .field-input, .breakcore .topbar-control, .breakcore .topbar-control kbd { border-radius: 0; } .breakcore .btn--primary { color: var(--crust); border-color: var(--mauve); box-shadow: 3px 3px 0 0 var(--green); } .breakcore .btn--primary:hover { background: var(--green); border-color: var(--green); color: var(--crust); box-shadow: 3px 3px 0 0 var(--mauve); } .breakcore .btn--primary:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 0 var(--mauve); } .breakcore .btn--danger { box-shadow: 3px 3px 0 0 color-mix(in srgb, var(--red) 60%, var(--crust)); } .breakcore .btn--danger:hover { box-shadow: 3px 3px 0 0 var(--mauve); } .breakcore .btn--danger:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 0 var(--mauve); } .breakcore .btn:focus-visible { border-color: var(--green); box-shadow: 0 0 0 2px var(--green); } .breakcore .field-input:focus { border-color: var(--green); background: color-mix(in srgb, var(--surface0) 85%, var(--green) 8%); box-shadow: 0 0 0 2px color-mix(in srgb, var(--green) 35%, transparent); } /* Ghost had no breakcore identity — drab subtext on faint surface, * near-invisible on the violet ground. Give it the neon outline. */ .breakcore .btn--ghost { color: var(--teal); border-color: color-mix(in srgb, var(--teal) 55%, transparent); background: color-mix(in srgb, var(--surface0) 60%, transparent); box-shadow: 3px 3px 0 0 color-mix(in srgb, var(--teal) 35%, var(--crust)); } .breakcore .btn--ghost:hover { color: var(--crust); background: var(--teal); border-color: var(--teal); box-shadow: 3px 3px 0 0 var(--mauve); } .breakcore .btn--ghost:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 0 var(--mauve); } /* Back-link → hard neon return tab. Impossible to miss against the * CRT-violet ground; same offset-block language as .btn--primary. */ .breakcore .back-link { font-family: var(--font-mono); font-style: normal; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.16em; color: var(--green); padding: 7px 13px; background: color-mix(in srgb, var(--crust) 65%, transparent); border: 1px solid var(--mauve); box-shadow: 3px 3px 0 0 var(--mauve); text-shadow: 0 0 6px color-mix(in srgb, var(--green) 50%, transparent); } .breakcore .back-link:hover, .breakcore .back-link:focus-visible { color: var(--crust); background: var(--green); border-color: var(--green); box-shadow: 3px 3px 0 0 var(--mauve); text-shadow: none; } .breakcore .back-link:active { transform: translate(3px, 3px); box-shadow: 0 0 0 0 var(--mauve); } /* Top-bar chrome — neon UI, not drab subtext. Mono caps + hard offset. */ .breakcore .topbar-control { font-family: var(--font-mono); font-style: normal; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--teal); background: color-mix(in srgb, var(--crust) 55%, transparent); border-color: color-mix(in srgb, var(--teal) 50%, transparent); } .breakcore .topbar-control:hover { color: var(--crust); background: var(--mauve); border-color: var(--mauve); box-shadow: 2px 2px 0 0 var(--green); } .breakcore .topbar-control:focus-visible { border-color: var(--green); box-shadow: 0 0 0 2px var(--green); } .breakcore .topbar-control--danger:hover { background: var(--red); border-color: var(--red); color: var(--rosewater); box-shadow: 2px 2px 0 0 var(--mauve); } .breakcore .topbar-divider { width: 2px; background: repeating-linear-gradient( 180deg, var(--mauve) 0 4px, transparent 4px 7px ); } /* Post prev/next nav — neon offset panels + acid eyebrow (was dim text). */ .breakcore .post-nav a { transition: box-shadow 0.15s ease, border-color 0.15s ease; } .breakcore .post-nav a:hover { border-color: var(--mauve); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mauve) 40%, transparent), 4px 4px 0 0 var(--mauve); } .breakcore .post-nav .pn-eyebrow { color: var(--green); font-family: var(--font-mono); letter-spacing: 0.18em; text-shadow: 0 0 6px color-mix(in srgb, var(--green) 45%, transparent); } /* Prose / code — CRT pass: terminal block, hazard inline code, neon * blockquote, hazard-tape rule. */ .breakcore .prose pre { color: var(--teal); background-color: color-mix(in srgb, var(--crust) 92%, transparent); background-image: repeating-linear-gradient( 0deg, rgba(0, 0, 0, 0) 0 2px, color-mix(in srgb, var(--mauve) 9%, transparent) 2px 3px, rgba(0, 0, 0, 0) 3px 4px ); border-color: var(--mauve); border-left-color: var(--green); box-shadow: 0 0 0 1px color-mix(in srgb, var(--mauve) 28%, transparent), 4px 4px 0 0 color-mix(in srgb, var(--mauve) 35%, var(--crust)); } .breakcore .prose pre code { color: inherit; } .breakcore .prose :not(pre) code { color: var(--yellow); background: color-mix(in srgb, var(--yellow) 12%, transparent); border-bottom-color: color-mix(in srgb, var(--yellow) 55%, transparent); } .breakcore .prose blockquote { border-left-color: var(--mauve); background: color-mix(in srgb, var(--mauve) 7%, transparent); box-shadow: -3px 0 14px -5px color-mix(in srgb, var(--mauve) 55%, transparent); padding: 0.5rem 0 0.5rem 1.4rem; } .breakcore .prose hr { height: 3px; opacity: 0.85; background: repeating-linear-gradient( 90deg, var(--mauve) 0 14px, var(--green) 14px 28px ); box-shadow: 0 0 10px color-mix(in srgb, var(--mauve) 40%, transparent); } .breakcore .prose hr::before { background: var(--green); box-shadow: 0 0 8px var(--green); } .breakcore .prose h3 { color: var(--pink); } .breakcore .prose h4 { color: var(--teal); } .breakcore .prose h5 { color: var(--green); font-family: var(--font-mono); } /* Scrollbar + caret — full-immersion chrome (no default OS bar). */ .breakcore { scrollbar-color: var(--mauve) var(--crust); caret-color: var(--mauve); } .breakcore ::-webkit-scrollbar { width: 11px; height: 11px; } .breakcore ::-webkit-scrollbar-track { background: var(--crust); } .breakcore ::-webkit-scrollbar-thumb { background: var(--mauve); border: 2px solid var(--crust); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--green) 50%, transparent); } .breakcore ::-webkit-scrollbar-thumb:hover { background: var(--green); } .breakcore ::-webkit-scrollbar-corner { background: var(--crust); } /* Prose links — magenta resting, acid-green on hover. */ .breakcore .prose a { text-decoration-color: color-mix(in srgb, var(--mauve) 55%, transparent); } .breakcore .prose a:hover { color: var(--green); text-decoration-color: var(--green); } /* Reading progress — acid scan with bloom. */ .breakcore .reading-progress { background: var(--green); box-shadow: 0 0 8px var(--green), 0 0 3px var(--mauve); } /* ───── Confirm dialog (replaces window.confirm) ───── */ .cdialog-overlay { position: fixed; inset: 0; z-index: 300; display: flex; align-items: center; justify-content: center; padding: 1rem; } .cdialog-backdrop { position: absolute; inset: 0; background: color-mix(in srgb, var(--crust) 60%, transparent); backdrop-filter: blur(8px); } .cdialog-panel { position: relative; width: 100%; max-width: 26rem; padding: 1.6rem 1.6rem 1.4rem; animation: cdialog-in 0.18s cubic-bezier(0.2, 0.7, 0.2, 1); } @keyframes cdialog-in { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } } .cdialog-title { font-family: var(--font-display); font-style: italic; font-weight: 600; font-size: 1.4rem; line-height: 1.15; color: var(--text); letter-spacing: -0.01em; } .cdialog-msg { font-family: var(--font-sans); font-size: 0.98rem; line-height: 1.55; color: var(--subtext1); margin-top: 0.6rem; } .cdialog-actions { display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 1.5rem; } /* Breakcore: hard edges + neon cap + chromatic title. */ .breakcore .cdialog-panel { border-radius: 0; padding-top: 1.85rem; } .breakcore .cdialog-panel::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 2px; background: linear-gradient(90deg, var(--mauve), var(--teal)); } .breakcore .cdialog-title { text-shadow: -1px 0 0 var(--teal), 1px 0 0 var(--mauve); } /* Toast error variant (replaces window.alert). */ .toast--error { border-left: 3px solid var(--red); color: var(--rosewater); cursor: pointer; } .toast--error::before { content: "⚠ "; color: var(--red); }