Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
master
parent
49bfa6bd8f
commit
ca01324f67
@ -1,302 +0,0 @@
|
||||
<script lang="ts">
|
||||
const images = [
|
||||
"https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?w=1200",
|
||||
"https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=1200",
|
||||
"https://images.unsplash.com/photo-1493246507139-91e8fad9978e?w=1200",
|
||||
"https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=1200",
|
||||
"https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=1200",
|
||||
"https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200"
|
||||
];
|
||||
|
||||
let section: HTMLElement | undefined;
|
||||
let progress = $state(0);
|
||||
|
||||
const clamp = (value: number, min = 0, max = 1) => {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
};
|
||||
|
||||
const eased = $derived(0.5 - Math.cos(progress * Math.PI) / 2);
|
||||
|
||||
const angle = $derived(72 - eased * 72);
|
||||
const bladeWidth = $derived(70 + eased * 170);
|
||||
const cosA = $derived(Math.cos((angle * Math.PI) / 180));
|
||||
const overlap = $derived(2 * bladeWidth * (1 - cosA));
|
||||
const scale = $derived(0.92 + eased * 0.08);
|
||||
|
||||
$effect(() => {
|
||||
if (!section) return;
|
||||
const scrollSection = section;
|
||||
|
||||
let frame: number | null = null;
|
||||
|
||||
const update = () => {
|
||||
const rect = scrollSection.getBoundingClientRect();
|
||||
const scrollable = scrollSection.offsetHeight - window.innerHeight;
|
||||
|
||||
if (scrollable <= 0) {
|
||||
progress = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
progress = clamp(-rect.top / scrollable);
|
||||
frame = null;
|
||||
};
|
||||
|
||||
const onScroll = () => {
|
||||
if (frame === null) {
|
||||
frame = requestAnimationFrame(update);
|
||||
}
|
||||
};
|
||||
|
||||
update();
|
||||
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
window.addEventListener("resize", update);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("scroll", onScroll);
|
||||
window.removeEventListener("resize", update);
|
||||
|
||||
if (frame !== null) {
|
||||
cancelAnimationFrame(frame);
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="scroll-section" bind:this={section}>
|
||||
<div class="sticky-stage">
|
||||
<div class="intro">
|
||||
<span>Cortina de fuelle</span>
|
||||
<h1>Scroll para abrir</h1>
|
||||
<p>
|
||||
Cada imagen ocupa una lama vertical. El scroll controla la apertura,
|
||||
la separación y el ángulo de giro.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="accordion"
|
||||
style="
|
||||
--angle: {angle}deg;
|
||||
--blade-width: {bladeWidth}px;
|
||||
--overlap: {overlap}px;
|
||||
--scale: {scale};
|
||||
"
|
||||
>
|
||||
{#each images as image, index}
|
||||
<article
|
||||
class:left={index % 2 === 0}
|
||||
class:right={index % 2 !== 0}
|
||||
class="blade"
|
||||
style="
|
||||
--image: url('{image}');
|
||||
--z: {images.length - index};
|
||||
"
|
||||
>
|
||||
<div class="blade-face">
|
||||
<div class="shine"></div>
|
||||
</div>
|
||||
</article>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="progress-bar">
|
||||
<div style="width: {progress * 100}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
background: #070707;
|
||||
color: white;
|
||||
font-family:
|
||||
Inter,
|
||||
ui-sans-serif,
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
.scroll-section {
|
||||
height: 320vh;
|
||||
position: relative;
|
||||
background:
|
||||
radial-gradient(circle at top, rgba(255, 255, 255, 0.14), transparent 36rem),
|
||||
linear-gradient(180deg, #111, #050505);
|
||||
}
|
||||
|
||||
.sticky-stage {
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
overflow: hidden;
|
||||
perspective: 1400px;
|
||||
}
|
||||
|
||||
.intro {
|
||||
position: absolute;
|
||||
top: 7vh;
|
||||
left: clamp(1.5rem, 5vw, 5rem);
|
||||
z-index: 10;
|
||||
max-width: 520px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.intro span {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.75rem;
|
||||
opacity: 0.65;
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.18em;
|
||||
}
|
||||
|
||||
.intro h1 {
|
||||
margin: 0;
|
||||
font-size: clamp(2.5rem, 6vw, 6rem);
|
||||
line-height: 0.95;
|
||||
letter-spacing: -0.06em;
|
||||
}
|
||||
|
||||
.intro p {
|
||||
max-width: 34rem;
|
||||
margin-top: 1.2rem;
|
||||
color: rgba(255, 255, 255, 0.68);
|
||||
font-size: clamp(1rem, 1.5vw, 1.2rem);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: min(94vw, 1320px);
|
||||
min-height: 540px;
|
||||
transform-style: preserve-3d;
|
||||
transform: scale(var(--scale)) rotateX(2deg);
|
||||
}
|
||||
|
||||
.blade {
|
||||
width: var(--blade-width);
|
||||
height: min(64vh, 560px);
|
||||
flex: 0 0 var(--blade-width);
|
||||
position: relative;
|
||||
z-index: var(--z);
|
||||
transform-style: preserve-3d;
|
||||
transition:
|
||||
width 80ms linear,
|
||||
flex-basis 80ms linear,
|
||||
margin-left 80ms linear,
|
||||
transform 80ms linear;
|
||||
}
|
||||
|
||||
.blade.left {
|
||||
transform-origin: left center;
|
||||
transform: rotateY(var(--angle));
|
||||
}
|
||||
|
||||
.blade.right {
|
||||
margin-left: calc(var(--overlap) * -1);
|
||||
transform-origin: right center;
|
||||
transform: rotateY(calc(var(--angle) * -1));
|
||||
}
|
||||
|
||||
.blade-face {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-image: var(--image);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
backface-visibility: hidden;
|
||||
box-shadow: 0 32px 80px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.blade:first-child .blade-face {
|
||||
border-top-left-radius: 24px;
|
||||
border-bottom-left-radius: 24px;
|
||||
box-shadow:
|
||||
0 32px 80px rgba(0, 0, 0, 0.55),
|
||||
inset 1px 0 0 rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.blade:last-child .blade-face {
|
||||
border-top-right-radius: 24px;
|
||||
border-bottom-right-radius: 24px;
|
||||
box-shadow:
|
||||
0 32px 80px rgba(0, 0, 0, 0.55),
|
||||
inset -1px 0 0 rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.blade-face::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 0, 0, 0.46),
|
||||
transparent 35%,
|
||||
rgba(255, 255, 255, 0.18) 55%,
|
||||
rgba(0, 0, 0, 0.36)
|
||||
);
|
||||
mix-blend-mode: soft-light;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.shine {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(
|
||||
115deg,
|
||||
transparent 0%,
|
||||
rgba(255, 255, 255, 0.22) 45%,
|
||||
transparent 62%
|
||||
);
|
||||
opacity: 0.35;
|
||||
transform: translateX(-35%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
position: absolute;
|
||||
bottom: 6vh;
|
||||
left: 50%;
|
||||
width: min(420px, 70vw);
|
||||
height: 3px;
|
||||
overflow: hidden;
|
||||
border-radius: 999px;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.progress-bar div {
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
background: white;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.accordion {
|
||||
width: 125vw;
|
||||
min-height: 430px;
|
||||
}
|
||||
|
||||
.blade {
|
||||
height: 52vh;
|
||||
}
|
||||
|
||||
.intro {
|
||||
top: 5vh;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,402 +0,0 @@
|
||||
<script lang="ts">
|
||||
import Curtain from './Curtain.svelte';
|
||||
</script>
|
||||
|
||||
<!--
|
||||
Five consecutive demos to compare:
|
||||
1. Raster image, anchor='right' (original behaviour, baseline)
|
||||
2. Raster image, anchor='center' (curtain opens from the middle)
|
||||
3. Inline SVG geometric mark, anchor='right' (vector at any blade count)
|
||||
4. Inline SVG geometric mark, anchor='center'
|
||||
5. Inline SVG typographic poster, anchor='left'
|
||||
|
||||
Scroll the page top-to-bottom: each section sticks while you fold its
|
||||
curtain, then releases.
|
||||
-->
|
||||
|
||||
<header class="intro">
|
||||
<div class="intro-inner">
|
||||
<span class="kicker">Curtain — refactor preview</span>
|
||||
<h1>Five demos, two faces, three anchors.</h1>
|
||||
<p>
|
||||
Scroll down. Each section uses a different combination of
|
||||
<code>image</code> / <code>face</code> Snippet and
|
||||
<code>anchor</code> so you can compare folds, sharpness, and seams
|
||||
between raster and vector content.
|
||||
</p>
|
||||
<p class="hint">↓ scroll</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ── Demo 1 ─────────────────────────────────────────────── -->
|
||||
<Curtain
|
||||
image="https://images.unsplash.com/photo-1483985988355-763728e1935b?w=2400&q=80"
|
||||
alt="Curtain showcase: city lights at dusk"
|
||||
anchor="right"
|
||||
scrollLength="200vh"
|
||||
>
|
||||
<section class="reveal reveal-warm">
|
||||
<div class="reveal-content">
|
||||
<span class="eyebrow">Demo 1 · raster · anchor: right</span>
|
||||
<h2>Photographic backdrop, classic right anchor.</h2>
|
||||
<p>The original behaviour. The curtain compresses to the right edge.</p>
|
||||
</div>
|
||||
</section>
|
||||
</Curtain>
|
||||
|
||||
<!-- ── Demo 2 ─────────────────────────────────────────────── -->
|
||||
<Curtain
|
||||
image="https://images.unsplash.com/photo-1518770660439-4636190af475?w=2400&q=80"
|
||||
alt="Curtain showcase: tech circuitry"
|
||||
anchor="center"
|
||||
scrollLength="200vh"
|
||||
>
|
||||
<section class="reveal reveal-cool">
|
||||
<div class="reveal-content">
|
||||
<span class="eyebrow">Demo 2 · raster · anchor: center</span>
|
||||
<h2>The curtain splits in the middle.</h2>
|
||||
<p>Two halves fold outward to their respective edges, like a stage curtain.</p>
|
||||
</div>
|
||||
</section>
|
||||
</Curtain>
|
||||
|
||||
<!-- ── Demo 3 ─────────────────────────────────────────────── -->
|
||||
<Curtain face={brandMark} alt="Active brand mark" anchor="right" scrollLength="200vh">
|
||||
<section class="reveal reveal-dark">
|
||||
<div class="reveal-content">
|
||||
<span class="eyebrow">Demo 3 · inline SVG · anchor: right</span>
|
||||
<h2>Vector face, crisp folds at any blade count.</h2>
|
||||
<p>
|
||||
No HTTP fetch, no resampling at the seams, recolours through
|
||||
<code>currentColor</code>. The same Snippet is rendered into each
|
||||
blade and clipped via the host translation.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</Curtain>
|
||||
|
||||
<!-- ── Demo 4 ─────────────────────────────────────────────── -->
|
||||
<Curtain face={pattern} alt="Geometric brand pattern" anchor="center" scrollLength="220vh">
|
||||
<section class="reveal reveal-dark">
|
||||
<div class="reveal-content">
|
||||
<span class="eyebrow">Demo 4 · inline SVG · anchor: center</span>
|
||||
<h2>Vector + double-door opening.</h2>
|
||||
<p>
|
||||
Geometry stays sharp through the whole fold, including the inner
|
||||
edges that disappear behind the seam.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</Curtain>
|
||||
|
||||
<!-- ── Demo 5 ─────────────────────────────────────────────── -->
|
||||
<Curtain
|
||||
face={poster}
|
||||
alt="Typographic poster"
|
||||
anchor="left"
|
||||
bladeCount={10}
|
||||
scrollLength="220vh"
|
||||
>
|
||||
<section class="reveal reveal-light">
|
||||
<div class="reveal-content">
|
||||
<span class="eyebrow">Demo 5 · inline SVG · anchor: left · 10 blades</span>
|
||||
<h2>Typography, more blades, left anchor.</h2>
|
||||
<p>
|
||||
With a larger blade count, the difference between raster and
|
||||
vector becomes obvious: vectors keep their letterforms intact
|
||||
even when the strip is one tenth of the original width.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</Curtain>
|
||||
|
||||
<footer class="end">
|
||||
<p>End of demos. <code>Curtain</code> accepts <code>image</code>, <code>face</code>, three anchors, and a controlled <code>progress</code> prop.</p>
|
||||
</footer>
|
||||
|
||||
<!-- ── SVG faces (inline, themed via currentColor / brand red) ── -->
|
||||
|
||||
{#snippet brandMark()}
|
||||
<svg
|
||||
viewBox="0 0 1280 720"
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
role="presentation"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="bg-grad" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#1a0606" />
|
||||
<stop offset="1" stop-color="#09090b" />
|
||||
</linearGradient>
|
||||
<pattern id="grid" width="48" height="48" patternUnits="userSpaceOnUse">
|
||||
<path d="M 48 0 L 0 0 0 48" fill="none" stroke="#27272a" stroke-width="1" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="1280" height="720" fill="url(#bg-grad)" />
|
||||
<rect width="1280" height="720" fill="url(#grid)" opacity="0.7" />
|
||||
<g
|
||||
fill="none"
|
||||
stroke="#dc2626"
|
||||
stroke-width="14"
|
||||
stroke-linecap="square"
|
||||
stroke-linejoin="miter"
|
||||
>
|
||||
<path d="M 540 460 L 640 240 L 740 460" />
|
||||
<path d="M 580 380 L 880 380" />
|
||||
</g>
|
||||
<text
|
||||
x="640"
|
||||
y="600"
|
||||
font-family="ui-monospace, 'JetBrains Mono', monospace"
|
||||
font-size="56"
|
||||
font-weight="600"
|
||||
fill="#fafafa"
|
||||
text-anchor="middle"
|
||||
letter-spacing="-2.5"
|
||||
>
|
||||
active
|
||||
</text>
|
||||
</svg>
|
||||
{/snippet}
|
||||
|
||||
{#snippet pattern()}
|
||||
<svg
|
||||
viewBox="0 0 1280 720"
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
role="presentation"
|
||||
>
|
||||
<defs>
|
||||
<radialGradient id="halo" cx="0.5" cy="0.5" r="0.7">
|
||||
<stop offset="0" stop-color="#7f1d1d" stop-opacity="0.55" />
|
||||
<stop offset="1" stop-color="#09090b" stop-opacity="1" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<rect width="1280" height="720" fill="#09090b" />
|
||||
<rect width="1280" height="720" fill="url(#halo)" />
|
||||
<g
|
||||
fill="none"
|
||||
stroke="#dc2626"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
>
|
||||
{#each Array(12) as _, i (i)}
|
||||
<circle
|
||||
cx="640"
|
||||
cy="360"
|
||||
r={60 + i * 26}
|
||||
opacity={1 - i * 0.07}
|
||||
/>
|
||||
{/each}
|
||||
</g>
|
||||
<g fill="#ef4444">
|
||||
{#each Array(80) as _, i (i)}
|
||||
<circle
|
||||
cx={(i * 89) % 1280}
|
||||
cy={(i * 53) % 720}
|
||||
r={(i % 4) * 1 + 1.5}
|
||||
opacity={0.25 + ((i * 17) % 100) / 200}
|
||||
/>
|
||||
{/each}
|
||||
</g>
|
||||
</svg>
|
||||
{/snippet}
|
||||
|
||||
{#snippet poster()}
|
||||
<svg
|
||||
viewBox="0 0 1280 720"
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
role="presentation"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="poster-bg" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#fef2f2" />
|
||||
<stop offset="1" stop-color="#fde2e2" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="1280" height="720" fill="url(#poster-bg)" />
|
||||
<text
|
||||
x="640"
|
||||
y="500"
|
||||
font-family="ui-monospace, 'JetBrains Mono', monospace"
|
||||
font-size="640"
|
||||
font-weight="700"
|
||||
fill="#b91c1c"
|
||||
text-anchor="middle"
|
||||
letter-spacing="-30"
|
||||
>
|
||||
0.1
|
||||
</text>
|
||||
<text
|
||||
x="120"
|
||||
y="120"
|
||||
font-family="ui-monospace, monospace"
|
||||
font-size="22"
|
||||
font-weight="500"
|
||||
fill="#7f1d1d"
|
||||
letter-spacing="4"
|
||||
>
|
||||
ACTIVE / RUNTIME / 2026
|
||||
</text>
|
||||
<text
|
||||
x="1160"
|
||||
y="680"
|
||||
font-family="ui-monospace, monospace"
|
||||
font-size="22"
|
||||
font-weight="500"
|
||||
fill="#7f1d1d"
|
||||
letter-spacing="4"
|
||||
text-anchor="end"
|
||||
>
|
||||
§ 0001
|
||||
</text>
|
||||
</svg>
|
||||
{/snippet}
|
||||
|
||||
<style>
|
||||
.intro,
|
||||
.end {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 60vh;
|
||||
padding: 4rem 2rem;
|
||||
background: #09090b;
|
||||
color: #fafafa;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intro-inner {
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.kicker {
|
||||
display: inline-block;
|
||||
padding: 0.3rem 0.8rem;
|
||||
border: 1px solid rgba(220, 38, 38, 0.4);
|
||||
background: rgba(220, 38, 38, 0.1);
|
||||
color: #f87171;
|
||||
border-radius: 999px;
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.18em;
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
|
||||
.intro h1 {
|
||||
margin: 0;
|
||||
font-size: clamp(2rem, 5vw, 3.5rem);
|
||||
line-height: 1.1;
|
||||
letter-spacing: -0.03em;
|
||||
}
|
||||
|
||||
.intro p {
|
||||
color: rgba(250, 250, 250, 0.7);
|
||||
max-width: 56ch;
|
||||
margin: 1.25rem auto 0;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.intro p code,
|
||||
.end code {
|
||||
font-family: ui-monospace, monospace;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
padding: 0.05em 0.35em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9em;
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
.hint {
|
||||
opacity: 0.5;
|
||||
margin-top: 2rem !important;
|
||||
font-size: 0.85rem !important;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.end {
|
||||
min-height: 35vh;
|
||||
}
|
||||
|
||||
.reveal {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
text-align: center;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.reveal-content {
|
||||
max-width: 680px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
padding: 0.3rem 0.75rem;
|
||||
border: 1px solid currentColor;
|
||||
border-radius: 999px;
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
|
||||
.reveal h2 {
|
||||
margin: 0 0 1.25rem;
|
||||
font-size: clamp(2rem, 5vw, 4rem);
|
||||
line-height: 1.05;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
|
||||
.reveal p {
|
||||
margin: 0;
|
||||
font-size: clamp(1rem, 1.4vw, 1.18rem);
|
||||
line-height: 1.55;
|
||||
opacity: 0.85;
|
||||
max-width: 56ch;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.reveal p code {
|
||||
font-family: ui-monospace, monospace;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
padding: 0.05em 0.35em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.reveal-warm {
|
||||
background:
|
||||
radial-gradient(circle at 25% 30%, rgba(255, 90, 40, 0.28), transparent 55%),
|
||||
radial-gradient(circle at 75% 70%, rgba(120, 70, 230, 0.22), transparent 55%),
|
||||
#0a0a0c;
|
||||
color: #fafafa;
|
||||
}
|
||||
|
||||
.reveal-cool {
|
||||
background:
|
||||
radial-gradient(circle at 50% 30%, rgba(56, 189, 248, 0.25), transparent 55%),
|
||||
radial-gradient(circle at 50% 90%, rgba(14, 165, 233, 0.2), transparent 55%),
|
||||
#0a1119;
|
||||
color: #f0f9ff;
|
||||
}
|
||||
|
||||
.reveal-dark {
|
||||
background:
|
||||
radial-gradient(circle at 50% 50%, rgba(220, 38, 38, 0.18), transparent 60%),
|
||||
#09090b;
|
||||
color: #fafafa;
|
||||
}
|
||||
|
||||
.reveal-light {
|
||||
background:
|
||||
radial-gradient(circle at 30% 30%, #fff 0%, #fef2f2 60%, #fee2e2 100%);
|
||||
color: #18181b;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Skip static prerender for the legacy aapp demo. The page still
|
||||
* relies on pre-service-schema App methods that the current runtime
|
||||
* no longer exposes; until it is migrated to
|
||||
* `createActiveApp({ services })`, render it on-demand only so the
|
||||
* static gate stays green and the page remains reachable in dev.
|
||||
*/
|
||||
export const prerender = false;
|
||||
@ -0,0 +1,2 @@
|
||||
/** Skip static prerender — uses pre-service-schema App API. See /test/aapp. */
|
||||
export const prerender = false;
|
||||
@ -0,0 +1,2 @@
|
||||
/** Skip static prerender — uses pre-service-schema App API. See /test/aapp. */
|
||||
export const prerender = false;
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Skip static prerender for the legacy ecosystem demo. Same reason as
|
||||
* `/test/aapp`: pre-service-schema App methods that the current
|
||||
* runtime no longer exposes. Migration to
|
||||
* `createActiveApp({ services })` is tracked in the codex audit
|
||||
* follow-up.
|
||||
*/
|
||||
export const prerender = false;
|
||||
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Skip static prerender for the legacy http demo. The page still
|
||||
* relies on pre-service-schema App methods that the current runtime
|
||||
* no longer exposes; render it on-demand only.
|
||||
*/
|
||||
export const prerender = false;
|
||||
@ -0,0 +1,2 @@
|
||||
/** Skip static prerender — uses pre-service-schema App API. See /test/aapp. */
|
||||
export const prerender = false;
|
||||
Loading…
Reference in new issue