diff options
| author | AlfaPC11 | 2026-07-26 13:57:46 +0300 |
|---|---|---|
| committer | AlfaPC11 | 2026-07-26 13:57:46 +0300 |
| commit | fd7ab50e0c07c8848dc3a577185218dbaa912a8f (patch) | |
| tree | 426a76ca5cabb199a0cd7ad7f8fe89554d8b636e | |
| parent | bb4b3c504551c912296ac098fb7a3b67330412f8 (diff) | |
| download | website-fd7ab50e0c07c8848dc3a577185218dbaa912a8f.tar.gz | |
fix mobile icons and strengthen the responsive compiler showcase
| -rw-r--r-- | frontend/src/components/Icon.astro | 48 | ||||
| -rw-r--r-- | frontend/src/layouts/SiteLayout.astro | 2 | ||||
| -rw-r--r-- | frontend/src/pages/index.astro | 54 | ||||
| -rw-r--r-- | frontend/src/styles/global.css | 304 |
4 files changed, 323 insertions, 85 deletions
diff --git a/frontend/src/components/Icon.astro b/frontend/src/components/Icon.astro new file mode 100644 index 0000000..677bbf3 --- /dev/null +++ b/frontend/src/components/Icon.astro @@ -0,0 +1,48 @@ +--- +// SPDX-FileCopyrightText: 2026 Leitwolf <xs-lang.chess031@slmails.com> +// SPDX-License-Identifier: AGPL-3.0-or-later + +interface Props { + name: + | "arrow" + | "braces" + | "check" + | "chip" + | "github" + | "layers" + | "modules" + | "native" + | "registers" + | "terminal"; + label?: string; +} + +const { name, label } = Astro.props; +const paths = { + arrow: '<path d="m5 12 14-14m-9 0h9v9"/>', + braces: '<path d="M9 3H7a2 2 0 0 0-2 2v4l-2 3 2 3v4a2 2 0 0 0 2 2h2M15 3h2a2 2 0 0 1 2 2v4l2 3-2 3v4a2 2 0 0 1-2 2h-2"/>', + check: '<path d="m4 12 5 5L20 6"/>', + chip: '<rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 1v3m6-3v3M9 20v3m6-3v3M1 9h3m-3 6h3m16-6h3m-3 6h3M10 10h4v4h-4z"/>', + github: + '<path d="M15 22v-3.9c.04-1-.35-1.96-1.1-2.6 3.6-.4 7.4-1.77 7.4-8A6.2 6.2 0 0 0 19.65 3 5.8 5.8 0 0 0 19.5 1S18.15.55 15 2.65a15.4 15.4 0 0 0-8 0C3.85.55 2.5 1 2.5 1a5.8 5.8 0 0 0-.15 2A6.2 6.2 0 0 0 .7 7.5c0 6.22 3.8 7.6 7.4 8-.73.63-1.1 1.55-1.1 2.5V22"/><path d="M7 19c-3 .9-3-1.5-4.2-2"/>', + layers: '<path d="m12 3-9 5 9 5 9-5-9-5Z"/><path d="m3 12 9 5 9-5M3 16l9 5 9-5"/>', + modules: '<rect x="3" y="3" width="7" height="7" rx="2"/><rect x="14" y="3" width="7" height="7" rx="2"/><rect x="8.5" y="14" width="7" height="7" rx="2"/><path d="M10 6.5h4M6.5 10v2l4 2M17.5 10v2l-4 2"/>', + native: '<rect x="3" y="4" width="18" height="16" rx="3"/><path d="m9 8 4 4-4 4m5 0h3"/>', + registers: '<path d="M4 6h16M4 12h16M4 18h16"/><circle cx="8" cy="6" r="2"/><circle cx="16" cy="12" r="2"/><circle cx="11" cy="18" r="2"/>', + terminal: '<rect x="3" y="4" width="18" height="16" rx="3"/><path d="m7 9 3 3-3 3m6 0h4"/>', +} satisfies Record<Props["name"], string>; +--- + +<svg + class="icon" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="1.75" + role={label ? "img" : undefined} + aria-hidden={label ? undefined : "true"} + aria-label={label} + set:html={paths[name]} +></svg> diff --git a/frontend/src/layouts/SiteLayout.astro b/frontend/src/layouts/SiteLayout.astro index c631220..27e0e41 100644 --- a/frontend/src/layouts/SiteLayout.astro +++ b/frontend/src/layouts/SiteLayout.astro @@ -17,7 +17,7 @@ const { title, description } = Astro.props; <head> <meta charset="UTF-8" /> <meta name="description" content={description} /> - <meta name="viewport" content="width=device-width" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#0c111b" /> <link rel="icon" type="image/png" href="/xsharp-logo.png" /> <link rel="preload" href="/fonts/AlfaSlabOne-Regular.woff2" as="font" type="font/woff2" crossorigin /> diff --git a/frontend/src/pages/index.astro b/frontend/src/pages/index.astro index bbdf835..045101e 100644 --- a/frontend/src/pages/index.astro +++ b/frontend/src/pages/index.astro @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import SiteLayout from "../layouts/SiteLayout.astro"; +import Icon from "../components/Icon.astro"; const pipeline = [ { short: "XS", label: "Source", detail: "syntax + AST" }, @@ -31,7 +32,16 @@ const principles = [ text: "Verified XLIL lowers through LLVM IR to object code and a platform-native .xse executable.", icon: "native", }, -]; +] as const; + +const capabilities = [ + { icon: "braces", label: "Structural AST", detail: "source fidelity" }, + { icon: "layers", label: "Typed HIR", detail: "semantic intent" }, + { icon: "modules", label: "Borrow checking", detail: "ownership safety" }, + { icon: "registers", label: "XLIL registry", detail: "portable lowering" }, + { icon: "chip", label: "LLVM backend", detail: "native codegen" }, + { icon: "terminal", label: "Test runner", detail: "isolated .xse" }, +] as const; --- <SiteLayout @@ -55,8 +65,8 @@ const principles = [ <a href="#pipeline">Pipeline</a> <a href="https://github.com/xss-lang/xs-project/tree/main/Spec" target="_blank" rel="noreferrer">Specification</a> <a class="nav-source" href="https://github.com/xss-lang/xs-project" target="_blank" rel="noreferrer"> - GitHub - <svg viewBox="0 0 16 16" aria-hidden="true"><path d="M4 12 12 4m-6 0h6v6" /></svg> + <Icon name="github" /> + <span>GitHub</span> </a> </nav> </header> @@ -76,7 +86,7 @@ const principles = [ <div class="actions"> <a class="button primary" href="https://github.com/xss-lang/xs-project" target="_blank" rel="noreferrer"> Explore the compiler - <svg viewBox="0 0 20 20" aria-hidden="true"><path d="m7 4 6 6-6 6" /></svg> + <Icon name="arrow" /> </a> <a class="button secondary glass-panel" href="https://github.com/xss-lang/xs-project/tree/main/Spec/Programs" target="_blank" rel="noreferrer"> View examples @@ -103,15 +113,15 @@ const principles = [ </div> <div class="floating-node node-source glass-panel"> - <span class="node-icon">{ }</span> + <span class="node-icon"><Icon name="braces" /></span> <span><strong>source.xs</strong><small>parsed</small></span> </div> <div class="floating-node node-ir glass-panel"> - <span class="node-icon">%r</span> + <span class="node-icon"><Icon name="registers" /></span> <span><strong>XLIL v0</strong><small>verified</small></span> </div> <div class="floating-node node-native glass-panel"> - <span class="node-icon">▶</span> + <span class="node-icon"><Icon name="native" /></span> <span><strong>native.xse</strong><small>linked</small></span> </div> @@ -129,6 +139,32 @@ const principles = [ </div> </section> + <section class="capabilities-section" aria-labelledby="capabilities-title"> + <div class="capabilities-copy"> + <p class="eyebrow">One compiler, visible end to end</p> + <h2 id="capabilities-title">Everything needed to understand the build.</h2> + <p> + X# keeps the useful machinery in the open. Inspect typed decisions, follow control flow, and retain a readable + record before native code is emitted. + </p> + <a class="text-link" href="https://github.com/xss-lang/xs-project/tree/main/docs" target="_blank" rel="noreferrer"> + Read the architecture <span>→</span> + </a> + </div> + <div class="capability-grid"> + {capabilities.map((item, index) => ( + <article class="capability-tile glass-panel"> + <span class="capability-icon"><Icon name={item.icon} /></span> + <div> + <h3>{item.label}</h3> + <p>{item.detail}</p> + </div> + <small>{String(index + 1).padStart(2, "0")}</small> + </article> + ))} + </div> + </section> + <section id="pipeline" class="pipeline-section"> <div class="section-heading"> <div> @@ -195,7 +231,9 @@ fn main() -> Long { <div class="cards"> {principles.map((item) => ( <article class="principle-card glass-panel"> - <div class={`principle-icon ${item.icon}`} aria-hidden="true"><span></span><i></i><b></b></div> + <div class={`principle-icon ${item.icon}`}> + <Icon name={item.icon} /> + </div> <span class="card-number">{item.number}</span> <h3>{item.title}</h3> <p>{item.text}</p> diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index ac04008..74bb4ef 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -86,6 +86,15 @@ a { -webkit-tap-highlight-color: transparent; } +.icon { + display: block; + width: 1.25rem; + height: 1.25rem; + flex: 0 0 auto; + overflow: visible; + pointer-events: none; +} + .ambient { position: fixed; z-index: -2; @@ -231,12 +240,8 @@ nav .nav-source { } .nav-source svg { - width: 1rem; - fill: none; - stroke: currentColor; - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 1.5; + width: 1.05rem; + height: 1.05rem; } .hero { @@ -346,11 +351,7 @@ h1 em { .button svg { width: 1.1rem; - fill: none; - stroke: currentColor; - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 1.7; + height: 1.1rem; } .primary { @@ -560,8 +561,11 @@ h1 em { border-radius: 0.65rem; color: var(--cyan); background: rgb(255 255 255 / 5%); - font-family: var(--font-code); - font-size: 0.75rem; +} + +.node-icon .icon { + width: 1.15rem; + height: 1.15rem; } .floating-node > span:last-child { @@ -661,14 +665,117 @@ h1 em { } .pipeline-section, +.capabilities-section, .showcase, .principles { - content-visibility: auto; - contain-intrinsic-size: auto 52rem; padding: 7rem 0; border-top: 1px solid rgb(255 255 255 / 8%); } +.capabilities-section { + display: grid; + grid-template-columns: minmax(0, 0.82fr) minmax(32rem, 1.18fr); + gap: 5rem; + align-items: center; +} + +.capabilities-copy h2 { + max-width: 11ch; + margin-bottom: 1.5rem; + font-size: clamp(2.7rem, 4.5vw, 4.4rem); +} + +.capabilities-copy > p { + max-width: 35rem; + margin: 0; + color: var(--muted); + font-size: 1.03rem; + line-height: 1.7; +} + +.capability-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.75rem; +} + +.capability-tile { + position: relative; + display: flex; + gap: 1rem; + align-items: center; + min-height: 7.5rem; + padding: 1rem; + overflow: hidden; + border-radius: 1.1rem; + transition: + transform 220ms ease, + border-color 220ms ease, + background-color 220ms ease; +} + +.capability-tile::after { + position: absolute; + right: -2.5rem; + bottom: -3.5rem; + width: 8rem; + height: 8rem; + border-radius: 50%; + background: radial-gradient(circle, rgb(109 231 221 / 12%), transparent 70%); + content: ""; +} + +.capability-tile:hover { + transform: translateY(-0.2rem); + border-color: rgb(109 231 221 / 30%); +} + +.capability-icon { + display: grid; + place-items: center; + width: 3.35rem; + height: 3.35rem; + flex: 0 0 auto; + border: 1px solid rgb(198 156 255 / 24%); + border-radius: 0.9rem; + color: var(--cyan); + background: + radial-gradient(circle at 35% 20%, rgb(255 255 255 / 12%), transparent 50%), + rgb(169 112 255 / 8%); + box-shadow: inset 0 1px 0 rgb(255 255 255 / 8%); +} + +.capability-icon .icon { + width: 1.45rem; + height: 1.45rem; +} + +.capability-tile h3, +.capability-tile p { + margin: 0; +} + +.capability-tile h3 { + font-size: 0.96rem; + font-weight: 600; +} + +.capability-tile p { + margin-top: 0.22rem; + color: var(--quiet); + font-family: var(--font-code); + font-size: 0.7rem; +} + +.capability-tile small { + position: absolute; + top: 0.7rem; + right: 0.8rem; + color: rgb(255 255 255 / 18%); + font-family: var(--font-code); + font-size: 0.62rem; +} + .section-heading { display: grid; grid-template-columns: 1fr 0.7fr; @@ -922,64 +1029,27 @@ h2 { } .principle-icon { - position: relative; - width: 4.5rem; - height: 4.5rem; + display: grid; + place-items: center; + width: 4.25rem; + height: 4.25rem; margin: 1.25rem 0 3.6rem; + border: 1px solid rgb(198 156 255 / 26%); + border-radius: 1.15rem; + color: var(--violet-bright); + background: rgb(168 112 255 / 8%); + box-shadow: + inset 0 1px 0 rgb(255 255 255 / 8%), + 0 1rem 2.5rem rgb(0 0 0 / 20%); } -.principle-icon span, -.principle-icon i, -.principle-icon b { - position: absolute; - display: block; - border: 1px solid rgb(198 156 255 / 50%); - background: rgb(168 112 255 / 9%); -} - -.layers span, -.layers i, -.layers b { - width: 3.2rem; - height: 2.2rem; - transform: rotate(30deg) skewX(-30deg); - border-radius: 0.35rem; -} - -.layers span { top: 0; left: 0.8rem; } -.layers i { top: 0.7rem; left: 0.45rem; opacity: 0.7; } -.layers b { top: 1.4rem; left: 0.1rem; opacity: 0.4; } - -.modules span, -.modules i, -.modules b { +.principle-icon .icon { width: 2rem; height: 2rem; - border-radius: 0.55rem; } -.modules span { top: 0; left: 0; } -.modules i { top: 0; right: 0; } -.modules b { bottom: 0; left: 1.25rem; } - -.native span { - inset: 0.2rem; - border-radius: 50%; - box-shadow: inset 0 0 1.5rem rgb(109 231 221 / 12%); -} - -.native i { - top: 1.45rem; - left: 1.7rem; - width: 0; - height: 0; - border-width: 0.75rem 0 0.75rem 1.2rem; - border-color: transparent transparent transparent var(--cyan); - background: transparent; -} - -.native b { - display: none; +.principle-icon.native { + color: var(--cyan); } .principle-card h3 { @@ -1128,6 +1198,15 @@ footer a { .showcase { gap: 3rem; } + + .capabilities-section { + grid-template-columns: 1fr; + gap: 3rem; + } + + .capabilities-copy h2 { + max-width: 14ch; + } } @media (max-width: 48rem) { @@ -1151,12 +1230,6 @@ footer a { justify-content: space-between; } - .hero-visual { - min-height: 35rem; - transform: scale(0.92); - transform-origin: center top; - } - .section-heading, .showcase { grid-template-columns: 1fr; @@ -1205,6 +1278,10 @@ footer a { grid-template-columns: 1fr; } + .capability-grid { + grid-template-columns: 1fr; + } + .principle-card { min-height: 17rem; } @@ -1226,10 +1303,84 @@ footer a { @media (max-width: 35rem) { .hero-visual { - left: 50%; - width: 34rem; - margin-left: -17rem; - transform: scale(0.76); + width: 100%; + min-height: 32rem; + } + + .visual-glow { + top: 4rem; + width: 17rem; + height: 17rem; + } + + .orbit-wide { + top: 5.5rem; + width: 100%; + height: 19rem; + } + + .orbit-tight { + top: 6.8rem; + width: 76%; + height: 17rem; + } + + .compiler-core { + top: 7.5rem; + width: 12rem; + height: 12rem; + border-radius: 3.4rem 4.5rem 3.6rem 4.8rem; + } + + .compiler-core img { + width: 6.25rem; + height: 6.25rem; + border-radius: 1.4rem; + } + + .compiler-core > span:last-child { + bottom: 0.85rem; + font-size: 0.58rem; + } + + .floating-node { + min-width: 8.2rem; + padding: 0.55rem; + } + + .node-source { + top: 3.1rem; + left: 0; + } + + .node-ir { + top: 15.5rem; + right: 0; + } + + .node-native { + top: 22.5rem; + left: 0; + } + + .build-console { + right: 0; + bottom: 0; + width: calc(100% - 1.25rem); + } + + .orbit-dot-a { + top: 5.5rem; + left: 7%; + } + + .orbit-dot-b { + top: 21rem; + right: 4%; + } + + .capability-tile { + min-height: 6.5rem; } .hero-facts span { @@ -1237,6 +1388,7 @@ footer a { } .pipeline-section, + .capabilities-section, .showcase, .principles { padding: 5rem 0; |