feat: Redesign homepage to a split layout with a brand sidebar, removing the interactive ASCII art controls.
This commit is contained in:
@@ -8,27 +8,118 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Syntaxbullet - Digital Wizard">
|
<Layout title="Syntaxbullet - Digital Wizard">
|
||||||
<div class="hero-wrapper">
|
<div class="split-layout">
|
||||||
<!-- Background Layer: ASCII Art -->
|
<!-- LEFT SIDEBAR: Content -->
|
||||||
<div class="ascii-layer">
|
<aside class="sidebar">
|
||||||
|
<div class="sidebar-content">
|
||||||
|
<div class="brand-group">
|
||||||
|
<h1 class="brand-title">SYNTAXBULLET</h1>
|
||||||
|
<div class="brand-subtitle">
|
||||||
|
FULL STACK ENGINEER
|
||||||
|
<span class="muted">//</span>
|
||||||
|
CREATIVE TECHNOLOGIST
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="brand-bio">
|
||||||
|
Crafting high-performance digital experiences at the
|
||||||
|
intersection of code, art, and artificial intelligence.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="sidebar-actions">
|
||||||
|
<a href="/projects" class="sidebar-link">
|
||||||
|
<span class="icon">⚡</span> PROJECTS
|
||||||
|
</a>
|
||||||
|
<a href="/blog" class="sidebar-link">
|
||||||
|
<span class="icon">📝</span> BLOG
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="mailto:contact@syntaxbullet.me"
|
||||||
|
class="sidebar-link"
|
||||||
|
>
|
||||||
|
<span class="icon">✉️</span> CONTACT
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-social">
|
||||||
|
<a
|
||||||
|
href="https://github.com/syntaxbullet"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
aria-label="GitHub"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
><path
|
||||||
|
d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"
|
||||||
|
></path><path d="M9 18c-4.51 2-5-2.64-5-2.64"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://linkedin.com/in/syntaxbullet"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
aria-label="LinkedIn"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
><path
|
||||||
|
d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"
|
||||||
|
></path><rect width="4" height="12" x="2" y="9"
|
||||||
|
></rect><circle cx="4" cy="4" r="2"></circle></svg
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://twitter.com/syntaxbullet"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
aria-label="Twitter"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
><path
|
||||||
|
d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<!-- RIGHT MAIN: ASCII & Controls -->
|
||||||
|
<main class="ascii-workspace hero-wrapper">
|
||||||
|
<!-- Canvas Layer -->
|
||||||
|
<div class="canvas-layer">
|
||||||
<div id="loading">Loading...</div>
|
<div id="loading">Loading...</div>
|
||||||
<pre id="ascii-result">Preparing art...</pre>
|
<pre id="ascii-result">Preparing art...</pre>
|
||||||
<canvas id="ascii-canvas"></canvas>
|
<canvas id="ascii-canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Foreground Layer: Content -->
|
|
||||||
<div class="content-layer">
|
|
||||||
<div class="max-w-container">
|
|
||||||
<main class="hero-content">
|
|
||||||
<div class="hero-text">
|
|
||||||
<h2>SYNTAXBULLET</h2>
|
|
||||||
<p class="tagline">
|
|
||||||
Self-taught Munich-based software engineer
|
|
||||||
passionate about Generative AI, Linux, and the Web.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer class="controls-footer">
|
<footer class="controls-footer">
|
||||||
<div id="tui-controls">
|
<div id="tui-controls">
|
||||||
<!-- Sliders Section -->
|
<!-- Sliders Section -->
|
||||||
@@ -130,10 +221,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="section-header" style="margin-top: 8px;">
|
||||||
class="section-header"
|
|
||||||
style="margin-top: 8px;"
|
|
||||||
>
|
|
||||||
OUTPUT
|
OUTPUT
|
||||||
</div>
|
</div>
|
||||||
<div class="segments-row">
|
<div class="segments-row">
|
||||||
@@ -212,9 +300,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
<div class="control-panel-divider-h"></div>
|
<div class="control-panel-divider-h"></div>
|
||||||
|
|
||||||
<div class="control-panel-section export-section">
|
<div class="control-panel-section export-section">
|
||||||
<div class="section-header">
|
<div class="section-header">IMPORT / EXPORT</div>
|
||||||
IMPORT / EXPORT
|
|
||||||
</div>
|
|
||||||
<div class="actions-row">
|
<div class="actions-row">
|
||||||
<!-- Hidden File Input -->
|
<!-- Hidden File Input -->
|
||||||
<input
|
<input
|
||||||
@@ -263,8 +349,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
<span><kbd>S</kbd> Charset</span>
|
<span><kbd>S</kbd> Charset</span>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</main>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -368,36 +453,161 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Layout Wrapper */
|
/* Split Layout */
|
||||||
.hero-wrapper {
|
.split-layout {
|
||||||
position: relative;
|
display: flex;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar (Left 25%) */
|
||||||
|
.sidebar {
|
||||||
|
width: 25%;
|
||||||
|
min-width: 320px;
|
||||||
|
max-width: 480px;
|
||||||
|
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
background: #000;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
box-shadow: 4px 0 20px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-content {
|
||||||
|
padding: 4rem 3rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-title {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-subtitle {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
letter-spacing: 1px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted {
|
||||||
|
color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-bio {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
text-decoration: none;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 4px 0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link:hover {
|
||||||
|
color: var(--text-color);
|
||||||
|
transform: translateX(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link .icon {
|
||||||
|
width: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-panel-divider-h {
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 32px 0;
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(255, 255, 255, 0.1) 20%,
|
||||||
|
rgba(255, 255, 255, 0.3) 50%,
|
||||||
|
rgba(255, 255, 255, 0.1) 80%,
|
||||||
|
transparent 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-social {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-social a {
|
||||||
|
color: rgba(255, 255, 255, 0.4);
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-social a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Workspace (Right 75%) */
|
||||||
|
.ascii-workspace {
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 100vh;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #050505;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BACKGROUND LAYER */
|
.canvas-layer {
|
||||||
.ascii-layer {
|
flex-grow: 1;
|
||||||
position: absolute;
|
position: relative;
|
||||||
top: 0;
|
display: flex;
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 0; /* Behind everything */
|
|
||||||
display: flex; /* Original centering logic */
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
pointer-events: none; /* Let clicks pass through to body/script */
|
overflow: hidden;
|
||||||
opacity: 0.6; /* Slight fade to let text pop */
|
background: radial-gradient(circle at center, #111 0%, #000 100%);
|
||||||
transition: opacity 0.5s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ascii-result {
|
#ascii-result {
|
||||||
font-size: 8px; /* Dynamic but starts here */
|
font-size: 8px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
/* If specific alignment needed for hero: */
|
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,152 +631,40 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
|
padding: 1rem 2rem;
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
padding: 10px 20px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
backdrop-filter: blur(4px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FOREGROUND LAYER */
|
/* Controls Footer */
|
||||||
.content-layer {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1; /* Above ASCII */
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: radial-gradient(
|
|
||||||
circle at center,
|
|
||||||
rgba(0, 0, 0, 0) 0%,
|
|
||||||
rgba(0, 0, 0, 0.4) 80%
|
|
||||||
); /* Subtle vignette */
|
|
||||||
pointer-events: none; /* Let clicks pass for image regen */
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-container {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 1440px;
|
|
||||||
margin: 0 auto;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make interactive elements clickable again */
|
|
||||||
.site-header,
|
|
||||||
.controls-footer,
|
|
||||||
.hero-text {
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't block clicks on pure layout areas if they are empty,
|
|
||||||
but hero-text might block image regen click if big.
|
|
||||||
Let's keep hero-text pointer-events auto only on text selection?
|
|
||||||
Actually user wants click anywhere to regen.
|
|
||||||
Let's make sure 'a' and 'button' are clickable, anything else triggers regen via body listener. */
|
|
||||||
.hero-text {
|
|
||||||
pointer-events: none; /* Let clicks through text area */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Center Hero Text */
|
|
||||||
.hero-content {
|
|
||||||
padding: 2rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-text h2 {
|
|
||||||
font-size: clamp(3rem, 8vw, 6rem);
|
|
||||||
line-height: 0.9;
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 900;
|
|
||||||
opacity: 0.9;
|
|
||||||
text-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
|
|
||||||
mix-blend-mode: difference; /* Cool effect over ASCII */
|
|
||||||
color: #fff; /* Make it pop against the blend */
|
|
||||||
}
|
|
||||||
|
|
||||||
.tagline {
|
|
||||||
margin-top: 1rem;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
opacity: 0.8;
|
|
||||||
max-width: 400px;
|
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer / Controls */
|
|
||||||
.controls-footer {
|
.controls-footer {
|
||||||
padding: 1.5rem;
|
flex-shrink: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.85);
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
gap: 1rem;
|
||||||
gap: 0.75rem;
|
z-index: 20;
|
||||||
position: relative;
|
|
||||||
z-index: 50; /* Ensure on top */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#tui-controls {
|
#tui-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: stretch; /* Stretch to same height */
|
|
||||||
gap: 0;
|
gap: 0;
|
||||||
|
background: none;
|
||||||
/* Glassmorphism update */
|
box-shadow: none;
|
||||||
background: rgba(10, 10, 10, 0.8);
|
border: none;
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
-webkit-backdrop-filter: blur(12px);
|
|
||||||
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
|
||||||
|
|
||||||
max-width: 100%;
|
|
||||||
border-radius: 8px; /* Slightly rounded for premium feel */
|
|
||||||
overflow: hidden; /* For border radius */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel-section {
|
.control-panel-section {
|
||||||
padding: 16px 20px;
|
padding: 0 20px;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-col-right {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel-divider {
|
.control-panel-divider {
|
||||||
width: 1px;
|
background: rgba(255, 255, 255, 0.1);
|
||||||
background: linear-gradient(
|
|
||||||
to bottom,
|
|
||||||
transparent 0%,
|
|
||||||
rgba(255, 255, 255, 0.1) 20%,
|
|
||||||
rgba(255, 255, 255, 0.3) 50%,
|
|
||||||
rgba(255, 255, 255, 0.1) 80%,
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
align-self: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-panel-divider-h {
|
|
||||||
height: 1px;
|
|
||||||
width: 100%;
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
transparent 0%,
|
|
||||||
rgba(255, 255, 255, 0.1) 20%,
|
|
||||||
rgba(255, 255, 255, 0.3) 50%,
|
|
||||||
rgba(255, 255, 255, 0.1) 80%,
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
@@ -574,7 +672,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 8px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
@@ -582,24 +680,13 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
.sliders-grid {
|
.sliders-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
gap: 8px 20px;
|
gap: 8px 16px;
|
||||||
}
|
|
||||||
|
|
||||||
.toggles-row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.segments-row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toggles-row,
|
||||||
|
.segments-row,
|
||||||
.actions-row {
|
.actions-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@@ -614,29 +701,12 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
border-left: 1px solid rgba(255, 255, 255, 0.2);
|
border-left: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-label {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.queue-value {
|
|
||||||
font-weight: bold;
|
|
||||||
min-width: 1.5ch;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shortcuts hint */
|
|
||||||
.shortcuts-hint {
|
.shortcuts-hint {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
font-size: 11px;
|
font-size: 10px;
|
||||||
opacity: 0.5;
|
opacity: 0.4;
|
||||||
transition: opacity 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shortcuts-hint:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.shortcuts-hint span {
|
.shortcuts-hint span {
|
||||||
@@ -646,150 +716,42 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
}
|
}
|
||||||
|
|
||||||
.shortcuts-hint kbd {
|
.shortcuts-hint kbd {
|
||||||
display: inline-flex;
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
align-items: center;
|
padding: 2px 4px;
|
||||||
justify-content: center;
|
border-radius: 3px;
|
||||||
min-width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
padding: 0 5px;
|
|
||||||
font-size: 10px;
|
|
||||||
font-family: inherit;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
||||||
border-radius: 4px;
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Legacy styles kept for compatibility */
|
|
||||||
.control-group {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tui-btn {
|
|
||||||
background: none;
|
|
||||||
border: 1px solid #333;
|
|
||||||
color: var(--text-color);
|
|
||||||
font-family: inherit;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 2px 6px;
|
|
||||||
font-weight: bold;
|
|
||||||
opacity: 0.7;
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tui-btn:hover {
|
|
||||||
opacity: 1;
|
|
||||||
border-color: var(--text-color);
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tui-val {
|
|
||||||
min-width: 3ch;
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive Adjustments */
|
|
||||||
@media (max-width: 900px) {
|
|
||||||
.sliders-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tui-controls {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-col-right {
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-col-right > .control-panel-section {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New vertical alignment for right col on mobile */
|
|
||||||
.control-panel-divider-h {
|
|
||||||
width: 1px;
|
|
||||||
height: auto;
|
|
||||||
align-self: stretch;
|
|
||||||
background: linear-gradient(
|
|
||||||
to bottom,
|
|
||||||
transparent 0%,
|
|
||||||
rgba(255, 255, 255, 0.2) 20%,
|
|
||||||
rgba(255, 255, 255, 0.2) 80%,
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-panel-divider {
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
transparent 0%,
|
|
||||||
rgba(255, 255, 255, 0.1) 20%,
|
|
||||||
rgba(255, 255, 255, 0.3) 50%,
|
|
||||||
rgba(255, 255, 255, 0.1) 80%,
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-panel-section {
|
|
||||||
padding: 12px 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.hero-text h2 {
|
|
||||||
font-size: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-col-right {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-panel-divider-h {
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
transparent,
|
|
||||||
rgba(255, 255, 255, 0.2),
|
|
||||||
transparent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls-footer {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shortcuts-hint {
|
|
||||||
display: none; /* Hide on mobile - too cramped */
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggles-row,
|
|
||||||
.segments-row {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions-row {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.control-panel-section {
|
|
||||||
padding: 10px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-header {
|
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.split-layout {
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
min-width: 0;
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-content {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-subtitle,
|
||||||
|
.sidebar-actions {
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascii-workspace {
|
||||||
|
height: 80vh; /* Give space for scroll */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -270,9 +270,12 @@ export class AsciiController {
|
|||||||
async calculateGrid(): Promise<GridCache | undefined> {
|
async calculateGrid(): Promise<GridCache | undefined> {
|
||||||
if (!this.currentImgUrl) return;
|
if (!this.currentImgUrl) return;
|
||||||
|
|
||||||
|
const parent = this.canvas.parentElement;
|
||||||
|
if (!parent) return;
|
||||||
|
|
||||||
const fontAspectRatio = 0.55;
|
const fontAspectRatio = 0.55;
|
||||||
const marginRatio = 0.2;
|
const marginRatio = 0.05; // Reduced margin for container fit
|
||||||
const screenW = window.innerWidth;
|
const screenW = parent.clientWidth;
|
||||||
const availW = screenW * (1 - marginRatio);
|
const availW = screenW * (1 - marginRatio);
|
||||||
|
|
||||||
let widthCols = Math.floor(availW / 6);
|
let widthCols = Math.floor(availW / 6);
|
||||||
@@ -337,12 +340,16 @@ export class AsciiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateCanvasSize(): void {
|
private updateCanvasSize(): void {
|
||||||
|
const parent = this.canvas.parentElement;
|
||||||
|
if (!parent) return;
|
||||||
|
|
||||||
const fontAspectRatio = 0.55;
|
const fontAspectRatio = 0.55;
|
||||||
const gridAspect = (this.cachedGrid.widthCols * fontAspectRatio) / this.cachedGrid.heightRows;
|
const gridAspect = (this.cachedGrid.widthCols * fontAspectRatio) / this.cachedGrid.heightRows;
|
||||||
const screenW = window.innerWidth;
|
|
||||||
const screenH = window.innerHeight;
|
const screenW = parent.clientWidth;
|
||||||
const maxW = screenW * 0.95;
|
const screenH = parent.clientHeight;
|
||||||
const maxH = screenH * 0.95;
|
const maxW = screenW * 0.98;
|
||||||
|
const maxH = screenH * 0.98;
|
||||||
|
|
||||||
let finalW: number, finalH: number;
|
let finalW: number, finalH: number;
|
||||||
if (gridAspect > maxW / maxH) {
|
if (gridAspect > maxW / maxH) {
|
||||||
|
|||||||
Reference in New Issue
Block a user