Compare commits
2 Commits
506762c538
...
038e1634eb
| Author | SHA1 | Date | |
|---|---|---|---|
| 038e1634eb | |||
| aaa58346d3 |
@@ -1,70 +1,75 @@
|
||||
<section class="section-card">
|
||||
<header class="section-header">
|
||||
<div class="header-copy">
|
||||
<p class="eyebrow">Back-office media</p>
|
||||
<h2>Media home</h2>
|
||||
<section class="section-card ui-section-card ui-stack ui-stack--roomy">
|
||||
<header class="section-header ui-section-header">
|
||||
<div class="header-copy ui-section-header__copy">
|
||||
<p class="eyebrow ui-eyebrow ui-eyebrow--compact">Back-office media</p>
|
||||
<h2 class="ui-section-header__title">Media home</h2>
|
||||
</div>
|
||||
<div class="header-side">
|
||||
<div class="header-stats">
|
||||
<article class="stat-chip">
|
||||
<div class="header-side ui-stack ui-stack--dense">
|
||||
<div class="header-stats ui-inline-actions">
|
||||
<article class="stat-chip ui-stat-chip">
|
||||
<strong>{{ configuredSectionCount }}</strong>
|
||||
<span>sezioni gestite</span>
|
||||
</article>
|
||||
<article class="stat-chip">
|
||||
<article class="stat-chip ui-stat-chip">
|
||||
<strong>{{ activeImageCount }}</strong>
|
||||
<span>immagini attive</span>
|
||||
</article>
|
||||
</div>
|
||||
<button type="button" (click)="loadHomeMedia()" [disabled]="loading">
|
||||
<button
|
||||
type="button"
|
||||
class="ui-button"
|
||||
(click)="loadHomeMedia()"
|
||||
[disabled]="loading"
|
||||
>
|
||||
Aggiorna
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<p class="status-banner status-banner-error" *ngIf="errorMessage">
|
||||
<p class="status-banner ui-banner ui-banner--error" *ngIf="errorMessage">
|
||||
{{ errorMessage }}
|
||||
</p>
|
||||
<p class="status-banner status-banner-success" *ngIf="successMessage">
|
||||
<p class="status-banner ui-banner ui-banner--success" *ngIf="successMessage">
|
||||
{{ successMessage }}
|
||||
</p>
|
||||
|
||||
<div class="group-stack" *ngIf="!loading; else loadingTpl">
|
||||
<section class="group-card" *ngFor="let group of sectionGroups">
|
||||
<header class="group-header">
|
||||
<div class="group-stack ui-stack" *ngIf="!loading; else loadingTpl">
|
||||
<section class="group-card ui-subpanel ui-subpanel--warm" *ngFor="let group of sectionGroups">
|
||||
<header class="group-header ui-row ui-row--between">
|
||||
<h3>{{ group.title }}</h3>
|
||||
</header>
|
||||
|
||||
<div class="sections">
|
||||
<div class="sections ui-stack ui-stack--dense">
|
||||
<section
|
||||
class="media-panel"
|
||||
class="media-panel ui-subpanel ui-subpanel--elevated"
|
||||
*ngFor="
|
||||
let section of getSectionsForGroup(group.id);
|
||||
trackBy: trackSection
|
||||
"
|
||||
>
|
||||
<header class="media-panel-header">
|
||||
<div class="media-panel-copy">
|
||||
<div class="title-row">
|
||||
<header class="media-panel-header ui-row ui-row--between ui-row--wrap">
|
||||
<div class="media-panel-copy ui-stack ui-stack--dense">
|
||||
<div class="title-row ui-row ui-row--center ui-row--wrap">
|
||||
<h4>{{ section.title }}</h4>
|
||||
<span class="count-pill">
|
||||
<span class="count-pill ui-pill ui-pill--soft">
|
||||
{{ section.items.length }}
|
||||
{{ section.items.length === 1 ? "attiva" : "attive" }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-panel-meta">
|
||||
<span class="usage-pill"
|
||||
<div class="media-panel-meta ui-row ui-row--wrap ui-row--end">
|
||||
<span class="usage-pill ui-pill ui-pill--neutral"
|
||||
>{{ section.usageType }} / {{ section.usageKey }}</span
|
||||
>
|
||||
<span class="layout-pill">
|
||||
<span class="layout-pill ui-pill ui-pill--light">
|
||||
Variante {{ section.preferredVariantName }}
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="workspace">
|
||||
<div class="upload-panel">
|
||||
<div class="panel-heading">
|
||||
<div class="workspace ui-workspace-compact">
|
||||
<div class="upload-panel ui-subpanel ui-subpanel--soft">
|
||||
<div class="panel-heading ui-stack ui-stack--dense">
|
||||
<h5>
|
||||
{{
|
||||
getFormState(section.usageKey).replacingUsageId
|
||||
@@ -74,9 +79,9 @@
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div class="form-field form-field--wide">
|
||||
<span>File immagine</span>
|
||||
<div class="form-grid ui-form-grid ui-form-grid--two">
|
||||
<div class="form-field form-field--wide ui-form-field">
|
||||
<span class="ui-form-caption">File immagine</span>
|
||||
<input
|
||||
[id]="'media-file-' + section.usageKey"
|
||||
class="sr-only"
|
||||
@@ -85,11 +90,13 @@
|
||||
(change)="onFileSelected(section.usageKey, $event)"
|
||||
/>
|
||||
<label
|
||||
class="file-picker"
|
||||
class="file-picker ui-file-picker"
|
||||
[for]="'media-file-' + section.usageKey"
|
||||
>
|
||||
<span class="file-picker-button">Scegli file</span>
|
||||
<span class="file-picker-name">
|
||||
<span class="file-picker-button ui-file-picker__button"
|
||||
>Scegli file</span
|
||||
>
|
||||
<span class="file-picker-name ui-file-picker__name">
|
||||
{{
|
||||
getFormState(section.usageKey).file?.name ||
|
||||
"Nessun file selezionato"
|
||||
@@ -107,16 +114,16 @@
|
||||
<img [src]="previewUrl" alt="" />
|
||||
</div>
|
||||
|
||||
<div class="language-toolbar form-field--wide">
|
||||
<div class="language-copy">
|
||||
<div class="language-toolbar form-field--wide ui-language-toolbar">
|
||||
<div class="language-copy ui-language-toolbar__copy">
|
||||
<span>Testi localizzati</span>
|
||||
<p>IT / EN / DE / FR obbligatorie</p>
|
||||
</div>
|
||||
<div class="language-toggle">
|
||||
<div class="language-toggle ui-language-toolbar__toggle">
|
||||
<button
|
||||
*ngFor="let language of mediaLanguages"
|
||||
type="button"
|
||||
class="language-toggle-btn"
|
||||
class="language-toggle-btn ui-language-toolbar__button"
|
||||
[class.active]="
|
||||
getFormState(section.usageKey).activeLanguage ===
|
||||
language
|
||||
@@ -134,8 +141,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="form-field">
|
||||
<span>
|
||||
<label class="form-field ui-form-field">
|
||||
<span class="ui-form-caption">
|
||||
Titolo ({{
|
||||
mediaLanguageLabels[
|
||||
getFormState(section.usageKey).activeLanguage
|
||||
@@ -143,14 +150,15 @@
|
||||
}})
|
||||
</span>
|
||||
<input
|
||||
class="ui-form-control"
|
||||
type="text"
|
||||
[(ngModel)]="getActiveTranslation(section.usageKey).title"
|
||||
placeholder="Titolo immagine"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label class="form-field">
|
||||
<span>
|
||||
<label class="form-field ui-form-field">
|
||||
<span class="ui-form-caption">
|
||||
Alt text ({{
|
||||
mediaLanguageLabels[
|
||||
getFormState(section.usageKey).activeLanguage
|
||||
@@ -158,15 +166,17 @@
|
||||
}})
|
||||
</span>
|
||||
<input
|
||||
class="ui-form-control"
|
||||
type="text"
|
||||
[(ngModel)]="getActiveTranslation(section.usageKey).altText"
|
||||
placeholder="Testo alternativo"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label class="form-field">
|
||||
<span>Sort order</span>
|
||||
<label class="form-field ui-form-field">
|
||||
<span class="ui-form-caption">Sort order</span>
|
||||
<input
|
||||
class="ui-form-control"
|
||||
type="number"
|
||||
[(ngModel)]="getFormState(section.usageKey).sortOrder"
|
||||
min="0"
|
||||
@@ -183,9 +193,10 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="upload-actions">
|
||||
<div class="upload-actions ui-row ui-row--wrap">
|
||||
<button
|
||||
type="button"
|
||||
class="ui-button"
|
||||
(click)="uploadForSection(section.usageKey)"
|
||||
[disabled]="
|
||||
getFormState(section.usageKey).saving ||
|
||||
@@ -202,7 +213,7 @@
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="ghost"
|
||||
class="ui-button ui-button--ghost"
|
||||
(click)="prepareAdd(section.usageKey)"
|
||||
[disabled]="getFormState(section.usageKey).saving"
|
||||
>
|
||||
@@ -210,7 +221,7 @@
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="ghost"
|
||||
class="ui-button ui-button--ghost"
|
||||
*ngIf="getFormState(section.usageKey).replacingUsageId"
|
||||
(click)="cancelReplace(section.usageKey)"
|
||||
[disabled]="getFormState(section.usageKey).saving"
|
||||
@@ -220,21 +231,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-panel">
|
||||
<div class="panel-heading">
|
||||
<div class="list-panel ui-subpanel ui-subpanel--soft">
|
||||
<div class="panel-heading ui-stack ui-stack--dense">
|
||||
<h5>Immagini attive</h5>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="media-list"
|
||||
class="media-list ui-media-list"
|
||||
*ngIf="section.items.length; else emptySectionState"
|
||||
>
|
||||
<article
|
||||
class="media-item"
|
||||
class="media-item ui-media-item"
|
||||
*ngFor="let item of section.items; trackBy: trackItem"
|
||||
>
|
||||
<div class="thumb-wrap">
|
||||
<div class="thumb">
|
||||
<div class="thumb ui-thumb">
|
||||
<img
|
||||
*ngIf="item.previewUrl; else noPreviewTpl"
|
||||
[src]="item.previewUrl"
|
||||
@@ -243,8 +254,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="media-copy">
|
||||
<div class="media-copy-top">
|
||||
<div class="media-copy ui-stack ui-stack--dense">
|
||||
<div class="media-copy-top ui-row ui-row--between ui-row--center ui-row--wrap">
|
||||
<div>
|
||||
<h6>
|
||||
{{
|
||||
@@ -259,7 +270,9 @@
|
||||
{{ item.mediaAssetId }}
|
||||
</p>
|
||||
</div>
|
||||
<span class="primary-badge" *ngIf="item.isPrimary"
|
||||
<span
|
||||
class="primary-badge ui-pill ui-pill--accent"
|
||||
*ngIf="item.isPrimary"
|
||||
>Primaria</span
|
||||
>
|
||||
</div>
|
||||
@@ -283,10 +296,11 @@
|
||||
{{ item.createdAt | date: "short" }}
|
||||
</p>
|
||||
|
||||
<div class="sort-editor">
|
||||
<div class="sort-editor ui-row ui-row--wrap">
|
||||
<label>
|
||||
<span>Nuovo ordine</span>
|
||||
<span class="ui-form-caption">Nuovo ordine</span>
|
||||
<input
|
||||
class="ui-form-control"
|
||||
type="number"
|
||||
[(ngModel)]="item.draftSortOrder"
|
||||
min="0"
|
||||
@@ -294,7 +308,7 @@
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
class="ghost"
|
||||
class="ui-button ui-button--ghost"
|
||||
(click)="saveSortOrder(item)"
|
||||
[disabled]="
|
||||
isUsageBusy(item.usageId) ||
|
||||
@@ -305,10 +319,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="item-actions">
|
||||
<div class="item-actions ui-row ui-row--wrap">
|
||||
<button
|
||||
type="button"
|
||||
class="ghost"
|
||||
class="ui-button ui-button--ghost"
|
||||
(click)="prepareReplace(section.usageKey, item)"
|
||||
[disabled]="isUsageBusy(item.usageId)"
|
||||
>
|
||||
@@ -316,7 +330,7 @@
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="ghost"
|
||||
class="ui-button ui-button--ghost"
|
||||
(click)="setPrimary(item)"
|
||||
[disabled]="isUsageBusy(item.usageId) || item.isPrimary"
|
||||
>
|
||||
@@ -324,7 +338,7 @@
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="ghost danger"
|
||||
class="ui-button ui-button--ghost-danger"
|
||||
(click)="removeFromHome(item)"
|
||||
[disabled]="isUsageBusy(item.usageId)"
|
||||
>
|
||||
@@ -342,18 +356,18 @@
|
||||
</div>
|
||||
|
||||
<ng-template #emptySectionState>
|
||||
<p class="empty-state">
|
||||
<p class="empty-state ui-empty-state">
|
||||
Nessuna immagine attiva collegata a questa sezione home.
|
||||
</p>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #noPreviewTpl>
|
||||
<div class="thumb thumb-empty">
|
||||
<div class="thumb thumb-empty ui-thumb ui-thumb--empty">
|
||||
<span>Preview non disponibile</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
</section>
|
||||
|
||||
<ng-template #loadingTpl>
|
||||
<p class="loading-state">Caricamento media home...</p>
|
||||
<p class="loading-state ui-empty-state">Caricamento media home...</p>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,286 +1,5 @@
|
||||
.section-card {
|
||||
display: grid;
|
||||
gap: var(--space-5);
|
||||
}
|
||||
|
||||
.section-header,
|
||||
.media-panel-header,
|
||||
.media-copy-top,
|
||||
.upload-actions,
|
||||
.item-actions,
|
||||
.sort-editor {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 var(--space-2);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.14em;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-secondary-600);
|
||||
}
|
||||
|
||||
.header-copy h2,
|
||||
.media-panel-header h4,
|
||||
.panel-heading h5,
|
||||
.media-copy h6,
|
||||
.group-header h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-copy p,
|
||||
.media-panel-header p,
|
||||
.group-header p,
|
||||
.panel-heading p,
|
||||
.empty-state,
|
||||
.meta {
|
||||
margin: var(--space-2) 0 0;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.header-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.header-stats {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.header-side > button {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.stat-chip {
|
||||
min-width: 128px;
|
||||
padding: 0.75rem 0.9rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--color-border);
|
||||
background: linear-gradient(180deg, #fffdf5 0%, #ffffff 100%);
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.stat-chip strong {
|
||||
font-size: 1.15rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stat-chip span {
|
||||
font-size: 0.8rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.status-banner {
|
||||
margin: 0;
|
||||
padding: 0.85rem 1rem;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid transparent;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-banner-error {
|
||||
color: #8a241d;
|
||||
background: #fff1f0;
|
||||
border-color: #f2c3bf;
|
||||
}
|
||||
|
||||
.status-banner-success {
|
||||
color: #20613a;
|
||||
background: #eef9f1;
|
||||
border-color: #b7e3c4;
|
||||
}
|
||||
|
||||
.group-stack {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.group-card {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: calc(var(--radius-lg) + 2px);
|
||||
padding: clamp(12px, 1.8vw, 18px);
|
||||
background: linear-gradient(180deg, #fcfbf8 0%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.group-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-4);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
|
||||
.sections {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.media-panel {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: #ffffff;
|
||||
padding: var(--space-3);
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
.usage-pill,
|
||||
.primary-badge,
|
||||
.count-pill,
|
||||
.layout-pill {
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--color-border);
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.usage-pill {
|
||||
background: var(--color-neutral-100);
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.layout-pill {
|
||||
background: #f7f4e7;
|
||||
color: var(--color-neutral-900);
|
||||
}
|
||||
|
||||
.count-pill {
|
||||
background: #f8f9fb;
|
||||
color: var(--color-neutral-900);
|
||||
}
|
||||
|
||||
.primary-badge {
|
||||
background: #fff5b8;
|
||||
color: var(--color-text);
|
||||
border-color: #f1d65c;
|
||||
}
|
||||
|
||||
.media-panel-copy,
|
||||
.media-panel-meta,
|
||||
.panel-heading {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.media-panel-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.title-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.workspace {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
|
||||
gap: var(--space-3);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.upload-panel,
|
||||
.list-panel {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: linear-gradient(180deg, #fcfcfb 0%, #f7f7f4 100%);
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: var(--space-2);
|
||||
margin-top: var(--space-2);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
|
||||
.form-field {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.language-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-2);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: #fbfaf6;
|
||||
}
|
||||
|
||||
.language-copy {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.language-copy span {
|
||||
font-size: 0.76rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.language-copy p {
|
||||
margin: 0;
|
||||
font-size: 0.76rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.language-toggle {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.language-toggle-btn {
|
||||
min-width: 2.8rem;
|
||||
padding: 0.4rem 0.6rem;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 999px;
|
||||
background: #ffffff;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.language-toggle-btn.complete {
|
||||
border-color: #c9d8c4;
|
||||
}
|
||||
|
||||
.language-toggle-btn.incomplete {
|
||||
border-color: #e8c8c2;
|
||||
}
|
||||
|
||||
.language-toggle-btn.active {
|
||||
background: #fff5b8;
|
||||
border-color: var(--color-brand);
|
||||
color: var(--color-text);
|
||||
.form-field--wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
@@ -295,83 +14,18 @@
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.form-field--wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.form-field > span,
|
||||
.sort-editor span {
|
||||
font-size: 0.76rem;
|
||||
color: var(--color-text-muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.file-picker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-2);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-bg-card);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color 0.2s ease,
|
||||
background-color 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.file-picker:hover {
|
||||
border-color: var(--color-brand);
|
||||
background: #fffef8;
|
||||
}
|
||||
|
||||
.file-picker-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 6.25rem;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: calc(var(--radius-md) - 2px);
|
||||
background: #ffffff;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.file-picker-name {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
background: var(--color-bg-card);
|
||||
font: inherit;
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.toggle {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
width: auto;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 999px;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
background: var(--color-bg-card);
|
||||
align-self: end;
|
||||
justify-self: start;
|
||||
width: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -384,16 +38,16 @@ input {
|
||||
.toggle-mark {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
border-radius: 0.3rem;
|
||||
border: 1px solid var(--color-border);
|
||||
background: #ffffff;
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 0.3rem;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.toggle input:checked + .toggle-mark {
|
||||
background: #b14fb8;
|
||||
border-color: #b14fb8;
|
||||
background: var(--color-brand);
|
||||
border-color: var(--color-brand);
|
||||
}
|
||||
|
||||
.toggle input:checked + .toggle-mark::after {
|
||||
@@ -421,188 +75,36 @@ input {
|
||||
background: var(--color-bg-card);
|
||||
}
|
||||
|
||||
.preview-card img,
|
||||
.thumb img {
|
||||
.preview-card img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.media-list {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.media-item {
|
||||
display: grid;
|
||||
grid-template-columns: 168px minmax(0, 1fr);
|
||||
gap: var(--space-2);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 0.75rem;
|
||||
background: var(--color-bg-card);
|
||||
}
|
||||
|
||||
.thumb-wrap {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.thumb {
|
||||
aspect-ratio: 16 / 10;
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--color-neutral-200);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.thumb-empty {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
text-align: center;
|
||||
color: var(--color-text-muted);
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
.media-copy {
|
||||
min-width: 0;
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.media-copy-top {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.media-copy h5 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.media-copy h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.meta {
|
||||
margin: 0;
|
||||
font-size: 0.82rem;
|
||||
color: var(--color-text-muted);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.sort-editor {
|
||||
align-items: end;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sort-editor label {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.upload-actions {
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.upload-actions button {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-brand);
|
||||
color: var(--color-neutral-900);
|
||||
padding: var(--space-2) var(--space-4);
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
opacity 0.2s ease,
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
button:hover:not(:disabled) {
|
||||
background: var(--color-brand-hover);
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.65;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
button.ghost {
|
||||
background: var(--color-bg-card);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
button.ghost:hover:not(:disabled) {
|
||||
background: #fff8cc;
|
||||
border-color: var(--color-brand);
|
||||
}
|
||||
|
||||
button.ghost.danger:hover:not(:disabled) {
|
||||
background: #fff0f0;
|
||||
border-color: #d9534f;
|
||||
}
|
||||
|
||||
.loading-state {
|
||||
margin: 0;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.workspace {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
min-width: min(100%, 180px);
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.form-grid,
|
||||
.media-item {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.language-toolbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.language-toggle {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.file-picker {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.file-picker-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.section-header,
|
||||
.header-side,
|
||||
.header-stats,
|
||||
.group-header,
|
||||
.media-panel-header,
|
||||
.media-copy-top,
|
||||
.upload-actions,
|
||||
.item-actions,
|
||||
.sort-editor {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.usage-pill,
|
||||
.primary-badge,
|
||||
.count-pill,
|
||||
.layout-pill {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.media-panel-meta {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.sort-editor {
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
<main class="home-page">
|
||||
<section class="hero">
|
||||
<div class="container hero-grid">
|
||||
<div class="container hero-grid ui-content-grid ui-content-grid--spacious">
|
||||
<div class="hero-copy">
|
||||
<p class="eyebrow">{{ "HOME.HERO_EYEBROW" | translate }}</p>
|
||||
<h1 class="hero-title" [innerHTML]="'HOME.HERO_TITLE' | translate"></h1>
|
||||
<p class="hero-lead">
|
||||
<p class="eyebrow ui-eyebrow">{{ "HOME.HERO_EYEBROW" | translate }}</p>
|
||||
<h1
|
||||
class="hero-title ui-hero-display"
|
||||
[innerHTML]="'HOME.HERO_TITLE' | translate"
|
||||
></h1>
|
||||
<p class="hero-lead ui-copy-lead">
|
||||
{{ "HOME.HERO_LEAD" | translate }}
|
||||
</p>
|
||||
<p class="hero-subtitle">
|
||||
<p class="hero-subtitle ui-copy-subtitle">
|
||||
{{ "HOME.HERO_SUBTITLE" | translate }}
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<div class="hero-actions ui-inline-actions ui-inline-actions--wide">
|
||||
<app-button variant="primary" routerLink="/calculator/basic">{{
|
||||
"HOME.BTN_CALCULATE" | translate
|
||||
}}</app-button>
|
||||
@@ -25,12 +28,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section capabilities">
|
||||
<section class="section capabilities ui-section-block">
|
||||
<div class="capabilities-bg"></div>
|
||||
<div class="container">
|
||||
<div class="section-head">
|
||||
<h2 class="section-title">{{ "HOME.SEC_CAP_TITLE" | translate }}</h2>
|
||||
<p class="section-subtitle">
|
||||
<div class="section-head ui-section-head">
|
||||
<h2 class="section-title ui-section-display-title">
|
||||
{{ "HOME.SEC_CAP_TITLE" | translate }}
|
||||
</h2>
|
||||
<p class="section-subtitle ui-section-display-subtitle">
|
||||
{{ "HOME.SEC_CAP_SUBTITLE" | translate }}
|
||||
</p>
|
||||
</div>
|
||||
@@ -38,7 +43,7 @@
|
||||
<app-card
|
||||
*ngFor="let card of capabilityCards(); trackBy: trackCapability"
|
||||
>
|
||||
<div class="card-image-placeholder">
|
||||
<div class="card-image-placeholder ui-bleed-media">
|
||||
@if (card.image; as image) {
|
||||
<picture>
|
||||
@if (image.source.avifUrl) {
|
||||
@@ -55,23 +60,27 @@
|
||||
/>
|
||||
</picture>
|
||||
} @else {
|
||||
<div class="card-image-fallback">
|
||||
<div class="card-image-fallback ui-bleed-media__fallback">
|
||||
<span>{{ card.titleKey | translate }}</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<h3>{{ card.titleKey | translate }}</h3>
|
||||
<p class="text-muted">{{ card.textKey | translate }}</p>
|
||||
<p class="text-muted ui-text-muted">{{ card.textKey | translate }}</p>
|
||||
</app-card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section calculator">
|
||||
<div class="container calculator-grid">
|
||||
<section class="section calculator ui-section-block">
|
||||
<div
|
||||
class="container calculator-grid ui-content-grid ui-content-grid--start ui-content-grid--split"
|
||||
>
|
||||
<div class="calculator-copy">
|
||||
<h2 class="section-title">{{ "HOME.SEC_CALC_TITLE" | translate }}</h2>
|
||||
<p class="section-subtitle">
|
||||
<h2 class="section-title ui-section-display-title">
|
||||
{{ "HOME.SEC_CALC_TITLE" | translate }}
|
||||
</h2>
|
||||
<p class="section-subtitle ui-section-display-subtitle">
|
||||
{{ "HOME.SEC_CALC_SUBTITLE" | translate }}
|
||||
</p>
|
||||
<ul class="calculator-list">
|
||||
@@ -79,23 +88,25 @@
|
||||
</ul>
|
||||
</div>
|
||||
<app-card class="quote-card">
|
||||
<div class="quote-header">
|
||||
<div class="quote-header ui-row ui-row--between">
|
||||
<div>
|
||||
<p class="quote-eyebrow">
|
||||
<p class="quote-eyebrow ui-eyebrow ui-eyebrow--compact">
|
||||
{{ "HOME.CARD_CALC_EYEBROW" | translate }}
|
||||
</p>
|
||||
<h3 class="quote-title">
|
||||
{{ "HOME.CARD_CALC_TITLE" | translate }}
|
||||
</h3>
|
||||
</div>
|
||||
<span class="quote-tag">{{ "HOME.CARD_CALC_TAG" | translate }}</span>
|
||||
<span class="quote-tag ui-pill ui-pill--accent">{{
|
||||
"HOME.CARD_CALC_TAG" | translate
|
||||
}}</span>
|
||||
</div>
|
||||
<ul class="quote-steps">
|
||||
<ul class="quote-steps ui-feature-list ui-feature-list--bullets">
|
||||
<li>{{ "HOME.CARD_CALC_STEP_1" | translate }}</li>
|
||||
<li>{{ "HOME.CARD_CALC_STEP_2" | translate }}</li>
|
||||
<li>{{ "HOME.CARD_CALC_STEP_3" | translate }}</li>
|
||||
</ul>
|
||||
<div class="quote-actions">
|
||||
<div class="quote-actions ui-actions ui-actions--stack">
|
||||
<app-button
|
||||
variant="primary"
|
||||
[fullWidth]="true"
|
||||
@@ -113,10 +124,12 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section shop">
|
||||
<div class="container split">
|
||||
<section class="section shop ui-section-block">
|
||||
<div class="container split ui-content-grid ui-content-grid--start ui-content-grid--split">
|
||||
<div class="shop-copy">
|
||||
<h2 class="section-title">{{ "HOME.SEC_SHOP_TITLE" | translate }}</h2>
|
||||
<h2 class="section-title ui-section-display-title">
|
||||
{{ "HOME.SEC_SHOP_TITLE" | translate }}
|
||||
</h2>
|
||||
<p>
|
||||
{{ "HOME.SEC_SHOP_TEXT" | translate }}
|
||||
</p>
|
||||
@@ -125,7 +138,7 @@
|
||||
<li>{{ "HOME.SEC_SHOP_LIST_2" | translate }}</li>
|
||||
<li>{{ "HOME.SEC_SHOP_LIST_3" | translate }}</li>
|
||||
</ul>
|
||||
<div class="shop-actions">
|
||||
<div class="shop-actions ui-inline-actions">
|
||||
<app-button variant="primary" routerLink="/shop">{{
|
||||
"HOME.BTN_DISCOVER" | translate
|
||||
}}</app-button>
|
||||
@@ -135,12 +148,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="shop-gallery"
|
||||
class="shop-gallery ui-gallery-strip"
|
||||
tabindex="0"
|
||||
[attr.aria-label]="'HOME.SHOP_GALLERY_ARIA' | translate"
|
||||
>
|
||||
<figure
|
||||
class="shop-gallery-item"
|
||||
class="shop-gallery-item ui-gallery-card"
|
||||
*ngFor="let image of shopGalleryImages(); trackBy: trackMediaAsset"
|
||||
>
|
||||
<picture>
|
||||
@@ -164,28 +177,36 @@
|
||||
<div class="shop-cards">
|
||||
<app-card>
|
||||
<h3>{{ "HOME.CARD_SHOP_1_TITLE" | translate }}</h3>
|
||||
<p class="text-muted">{{ "HOME.CARD_SHOP_1_TEXT" | translate }}</p>
|
||||
<p class="text-muted ui-text-muted">
|
||||
{{ "HOME.CARD_SHOP_1_TEXT" | translate }}
|
||||
</p>
|
||||
</app-card>
|
||||
<app-card>
|
||||
<h3>{{ "HOME.CARD_SHOP_2_TITLE" | translate }}</h3>
|
||||
<p class="text-muted">{{ "HOME.CARD_SHOP_2_TEXT" | translate }}</p>
|
||||
<p class="text-muted ui-text-muted">
|
||||
{{ "HOME.CARD_SHOP_2_TEXT" | translate }}
|
||||
</p>
|
||||
</app-card>
|
||||
<app-card>
|
||||
<h3>{{ "HOME.CARD_SHOP_3_TITLE" | translate }}</h3>
|
||||
<p class="text-muted">{{ "HOME.CARD_SHOP_3_TEXT" | translate }}</p>
|
||||
<p class="text-muted ui-text-muted">
|
||||
{{ "HOME.CARD_SHOP_3_TEXT" | translate }}
|
||||
</p>
|
||||
</app-card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section about">
|
||||
<div class="container about-grid">
|
||||
<section class="section about ui-section-block">
|
||||
<div class="container about-grid ui-content-grid ui-content-grid--start ui-content-grid--split">
|
||||
<div class="about-copy">
|
||||
<h2 class="section-title">{{ "HOME.SEC_ABOUT_TITLE" | translate }}</h2>
|
||||
<h2 class="section-title ui-section-display-title">
|
||||
{{ "HOME.SEC_ABOUT_TITLE" | translate }}
|
||||
</h2>
|
||||
<p>
|
||||
{{ "HOME.SEC_ABOUT_TEXT" | translate }}
|
||||
</p>
|
||||
<div class="about-actions">
|
||||
<div class="about-actions ui-inline-actions">
|
||||
<app-button variant="primary" routerLink="/about">{{
|
||||
"HOME.SEC_ABOUT_TITLE" | translate
|
||||
}}</app-button>
|
||||
@@ -195,7 +216,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="about-media">
|
||||
<div class="about-feature-image">
|
||||
<div class="about-feature-image ui-media-frame ui-media-frame--wide">
|
||||
@if (currentFounderImage(); as image) {
|
||||
<picture>
|
||||
@if (image.source.avifUrl) {
|
||||
@@ -218,7 +239,7 @@
|
||||
@if (founderImages().length > 1) {
|
||||
<button
|
||||
type="button"
|
||||
class="founder-nav founder-nav-prev"
|
||||
class="founder-nav founder-nav-prev ui-nav-button"
|
||||
(click)="prevFounderImage()"
|
||||
[attr.aria-label]="'HOME.FOUNDER_PREV_ARIA' | translate"
|
||||
>
|
||||
@@ -226,7 +247,7 @@
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="founder-nav founder-nav-next"
|
||||
class="founder-nav founder-nav-next ui-nav-button"
|
||||
(click)="nextFounderImage()"
|
||||
[attr.aria-label]="'HOME.FOUNDER_NEXT_ARIA' | translate"
|
||||
>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
padding: 6rem 0 5rem;
|
||||
overflow: hidden;
|
||||
background: var(--home-bg);
|
||||
// Enhanced Grid Pattern
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -24,7 +24,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the accent blob
|
||||
.hero::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -42,337 +41,70 @@
|
||||
animation: floatGlow 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.hero-grid {
|
||||
display: grid;
|
||||
gap: var(--space-12);
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-copy {
|
||||
animation: fadeUp 0.8s ease both;
|
||||
}
|
||||
.hero-panel {
|
||||
animation: fadeUp 0.8s ease 0.15s both;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-secondary-600);
|
||||
margin-bottom: var(--space-3);
|
||||
font-weight: 600;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: clamp(2.5rem, 2.4vw + 1.8rem, 4rem);
|
||||
font-weight: 700;
|
||||
line-height: 1.05;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: var(--space-4);
|
||||
}
|
||||
.hero-lead {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 500;
|
||||
color: var(--color-neutral-900);
|
||||
margin-bottom: var(--space-3);
|
||||
max-width: 600px;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 1.1rem;
|
||||
color: var(--color-text-muted);
|
||||
max-width: 560px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: var(--space-4);
|
||||
flex-wrap: wrap;
|
||||
margin: var(--space-6) 0 var(--space-4);
|
||||
}
|
||||
.hero-badges {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
.hero-badges span {
|
||||
display: inline-flex;
|
||||
padding: 0.35rem 0.75rem;
|
||||
border-radius: 999px;
|
||||
background: var(--color-neutral-100);
|
||||
color: var(--color-neutral-900);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.quote-card {
|
||||
display: block;
|
||||
}
|
||||
.focus-card {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
.focus-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
.focus-list li::before {
|
||||
content: "•";
|
||||
color: var(--color-brand);
|
||||
margin-right: var(--space-2);
|
||||
}
|
||||
.focus-list li {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
.quote-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-4);
|
||||
margin-bottom: var(--space-4);
|
||||
}
|
||||
.quote-eyebrow {
|
||||
text-transform: uppercase;
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--color-secondary-600);
|
||||
margin: 0 0 var(--space-2);
|
||||
}
|
||||
.quote-title {
|
||||
margin: 0;
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
.quote-tag {
|
||||
background: var(--color-neutral-100);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 999px;
|
||||
padding: 0.35rem 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-brand-600);
|
||||
background: var(--color-brand-50);
|
||||
border-color: var(--color-brand-200);
|
||||
}
|
||||
.quote-steps {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 0 var(--space-5);
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
.quote-steps li {
|
||||
position: relative;
|
||||
padding-left: 1.5rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
.quote-steps li::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-brand);
|
||||
position: absolute;
|
||||
left: 0.25rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
.quote-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: var(--space-4);
|
||||
margin-bottom: var(--space-5);
|
||||
}
|
||||
.meta-label {
|
||||
display: block;
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--color-secondary-600);
|
||||
margin-bottom: var(--space-1);
|
||||
}
|
||||
.meta-value {
|
||||
font-weight: 600;
|
||||
}
|
||||
.quote-actions {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.section.capabilities {
|
||||
.capabilities {
|
||||
position: relative;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
padding-top: 4.5rem;
|
||||
}
|
||||
|
||||
.capabilities-bg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 5.5rem 0;
|
||||
position: relative;
|
||||
}
|
||||
.section-head {
|
||||
margin-bottom: var(--space-8);
|
||||
}
|
||||
.section-title {
|
||||
font-size: clamp(2rem, 1.8vw + 1.2rem, 2.8rem);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
.section-subtitle {
|
||||
color: var(--color-text-muted);
|
||||
max-width: 620px;
|
||||
}
|
||||
.text-muted {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.calculator {
|
||||
position: relative;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.calculator-grid {
|
||||
display: grid;
|
||||
gap: var(--space-10);
|
||||
align-items: start;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.calculator-list {
|
||||
padding-left: var(--space-4);
|
||||
color: var(--color-text-muted);
|
||||
margin: var(--space-6) 0 0;
|
||||
}
|
||||
|
||||
.cap-cards {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
}
|
||||
|
||||
.card-image-placeholder {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
background: #f5f5f5;
|
||||
margin: -1.5rem -1.5rem 1.5rem -1.5rem; /* Negative margins to bleed to edge */
|
||||
width: calc(100% + 3rem);
|
||||
border-top-left-radius: var(--radius-lg);
|
||||
border-top-right-radius: var(--radius-lg);
|
||||
border-bottom: 1px solid var(--color-neutral-300);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-neutral-400);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-image-placeholder img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.quote-card {
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.card-image-placeholder picture {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-image-fallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-items: end start;
|
||||
padding: var(--space-4);
|
||||
background:
|
||||
linear-gradient(135deg, rgba(239, 196, 61, 0.22), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(180deg, #f8f5eb 0%, #efede6 100%);
|
||||
}
|
||||
|
||||
.card-image-fallback span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 2rem;
|
||||
padding: 0.35rem 0.7rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.88);
|
||||
border: 1px solid rgba(17, 24, 39, 0.08);
|
||||
color: var(--color-neutral-900);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.shop {
|
||||
background: var(--home-bg);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.shop .split {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.shop-copy {
|
||||
max-width: 760px;
|
||||
}
|
||||
.split {
|
||||
display: grid;
|
||||
gap: var(--space-10);
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.shop-list {
|
||||
padding-left: var(--space-4);
|
||||
color: var(--color-text-muted);
|
||||
margin-bottom: var(--space-6);
|
||||
}
|
||||
.shop-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.shop-gallery {
|
||||
display: flex;
|
||||
gap: var(--space-4);
|
||||
overflow-x: auto;
|
||||
scroll-snap-type: x mandatory;
|
||||
padding-bottom: var(--space-2);
|
||||
scrollbar-width: thin;
|
||||
width: min(100%, 440px);
|
||||
justify-self: end;
|
||||
aspect-ratio: 16 / 11;
|
||||
}
|
||||
|
||||
.shop-gallery-item {
|
||||
flex: 0 0 100%;
|
||||
margin: 0;
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-neutral-100);
|
||||
box-shadow: var(--shadow-sm);
|
||||
scroll-snap-align: start;
|
||||
aspect-ratio: 16 / 10;
|
||||
}
|
||||
|
||||
.shop-gallery-item img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.shop-gallery-item picture,
|
||||
.about-feature-image picture {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.shop-cards {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
@@ -393,34 +125,13 @@
|
||||
border-top: 1px solid var(--color-border);
|
||||
position: relative;
|
||||
}
|
||||
.about-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.about-grid {
|
||||
display: grid;
|
||||
gap: var(--space-10);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.about-media {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.about-feature-image {
|
||||
width: 100%;
|
||||
max-width: 620px;
|
||||
aspect-ratio: 16 / 10;
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--color-neutral-100);
|
||||
border: 1px solid var(--color-border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
contain: layout paint;
|
||||
}
|
||||
|
||||
.about-feature-photo {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@@ -430,109 +141,52 @@
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.founder-nav {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
background: rgba(17, 24, 39, 0.45);
|
||||
color: #fff;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.founder-nav:hover {
|
||||
background: rgba(17, 24, 39, 0.7);
|
||||
}
|
||||
|
||||
.founder-nav-prev {
|
||||
left: 0.75rem;
|
||||
}
|
||||
|
||||
.founder-nav-next {
|
||||
right: 0.75rem;
|
||||
}
|
||||
|
||||
.founder-nav:focus-visible {
|
||||
outline: 2px solid var(--color-brand);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.media-tile p {
|
||||
margin: 0;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.about-note {
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.hero-grid {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
}
|
||||
.calculator-grid {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
}
|
||||
.calculator-grid {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
}
|
||||
.split {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
}
|
||||
.shop-copy {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.shop-gallery {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.shop-cards {
|
||||
grid-column: 1 / -1;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
.about-grid {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.hero-actions {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.quote-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.shop-gallery {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
justify-self: stretch;
|
||||
}
|
||||
|
||||
.shop-gallery-item {
|
||||
aspect-ratio: 16 / 11;
|
||||
}
|
||||
|
||||
.shop-cards {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.about-media {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.about-feature-image {
|
||||
max-width: min(100%, 360px);
|
||||
aspect-ratio: 16 / 11;
|
||||
}
|
||||
.founder-nav {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeUp {
|
||||
@@ -540,26 +194,29 @@
|
||||
opacity: 0;
|
||||
transform: translateY(18px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes floatGlow {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(20px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.hero-copy,
|
||||
.hero-panel {
|
||||
.hero-copy {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,41 @@
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.ui-stack {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.ui-stack--dense {
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.ui-stack--roomy {
|
||||
gap: var(--space-5);
|
||||
}
|
||||
|
||||
.ui-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.ui-row--between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ui-row--center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ui-row--wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.ui-row--end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.ui-two-column-layout {
|
||||
--ui-sidebar-width: 400px;
|
||||
display: grid;
|
||||
@@ -82,6 +117,244 @@
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.ui-eyebrow {
|
||||
margin: 0 0 var(--space-3);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-secondary-600);
|
||||
}
|
||||
|
||||
.ui-eyebrow--compact {
|
||||
margin-bottom: var(--space-2);
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.ui-hero-display {
|
||||
margin: 0 0 var(--space-4);
|
||||
font-size: clamp(2.5rem, 2.4vw + 1.8rem, 4rem);
|
||||
font-weight: 700;
|
||||
line-height: 1.05;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.ui-copy-lead {
|
||||
margin: 0 0 var(--space-3);
|
||||
max-width: 600px;
|
||||
font-size: 1.35rem;
|
||||
font-weight: 500;
|
||||
color: var(--color-neutral-900);
|
||||
}
|
||||
|
||||
.ui-copy-subtitle {
|
||||
margin: 0;
|
||||
max-width: 560px;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.6;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-inline-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.ui-inline-actions--wide {
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.ui-section-block {
|
||||
position: relative;
|
||||
padding: 5.5rem 0;
|
||||
}
|
||||
|
||||
.ui-section-head {
|
||||
margin-bottom: var(--space-8);
|
||||
}
|
||||
|
||||
.ui-section-display-title {
|
||||
margin: 0 0 var(--space-3);
|
||||
font-size: clamp(2rem, 1.8vw + 1.2rem, 2.8rem);
|
||||
}
|
||||
|
||||
.ui-section-display-subtitle {
|
||||
margin: 0;
|
||||
max-width: 620px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-text-muted {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-content-grid {
|
||||
display: grid;
|
||||
gap: var(--space-10);
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.ui-content-grid--spacious {
|
||||
gap: var(--space-12);
|
||||
}
|
||||
|
||||
.ui-content-grid--start {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.ui-feature-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.ui-feature-list--bullets li {
|
||||
position: relative;
|
||||
padding-left: 1.5rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-feature-list--bullets li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0.25rem;
|
||||
top: 0.5rem;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-brand);
|
||||
}
|
||||
|
||||
.ui-bleed-media {
|
||||
width: calc(100% + 3rem);
|
||||
height: 160px;
|
||||
margin: -1.5rem -1.5rem 1.5rem;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top-left-radius: var(--radius-lg);
|
||||
border-top-right-radius: var(--radius-lg);
|
||||
border-bottom: 1px solid var(--color-neutral-300);
|
||||
background: #f5f5f5;
|
||||
color: var(--color-neutral-400);
|
||||
}
|
||||
|
||||
.ui-bleed-media img,
|
||||
.ui-bleed-media picture {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui-bleed-media img {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.ui-bleed-media__fallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-items: end start;
|
||||
padding: var(--space-4);
|
||||
background:
|
||||
linear-gradient(135deg, rgba(239, 196, 61, 0.22), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(180deg, #f8f5eb 0%, #efede6 100%);
|
||||
}
|
||||
|
||||
.ui-bleed-media__fallback span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 2rem;
|
||||
padding: 0.35rem 0.7rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.88);
|
||||
border: 1px solid rgba(17, 24, 39, 0.08);
|
||||
color: var(--color-neutral-900);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.ui-gallery-strip {
|
||||
display: flex;
|
||||
gap: var(--space-4);
|
||||
overflow-x: auto;
|
||||
scroll-snap-type: x mandatory;
|
||||
padding-bottom: var(--space-2);
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.ui-gallery-card {
|
||||
flex: 0 0 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--color-surface-muted);
|
||||
box-shadow: var(--shadow-sm);
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.ui-gallery-card picture,
|
||||
.ui-gallery-card img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui-gallery-card img {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.ui-media-frame {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--color-surface-muted);
|
||||
}
|
||||
|
||||
.ui-media-frame--wide {
|
||||
width: 100%;
|
||||
max-width: 620px;
|
||||
aspect-ratio: 16 / 10;
|
||||
contain: layout paint;
|
||||
}
|
||||
|
||||
.ui-nav-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
border-radius: 999px;
|
||||
background: rgba(17, 24, 39, 0.45);
|
||||
color: #fff;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.ui-nav-button:hover {
|
||||
background: rgba(17, 24, 39, 0.7);
|
||||
}
|
||||
|
||||
.ui-nav-button:focus-visible {
|
||||
outline: 2px solid var(--color-brand);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.ui-form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -151,6 +424,26 @@ select.ui-form-control {
|
||||
grid-template-columns: 1.5fr 2fr 1fr;
|
||||
}
|
||||
|
||||
.ui-form-grid {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.ui-form-grid--two {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.ui-form-field {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.ui-form-caption {
|
||||
font-size: 0.76rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-field-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -229,6 +522,111 @@ select.ui-form-control {
|
||||
background: var(--color-surface-muted);
|
||||
}
|
||||
|
||||
.ui-file-picker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-2);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-bg-card);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color 0.2s ease,
|
||||
background-color 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.ui-file-picker:hover {
|
||||
border-color: var(--color-brand);
|
||||
background: #fffef8;
|
||||
}
|
||||
|
||||
.ui-file-picker__button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 6.25rem;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: calc(var(--radius-md) - 2px);
|
||||
background: #ffffff;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-text);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ui-file-picker__name {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-language-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-2);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: #fbfaf6;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__copy {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__copy span {
|
||||
font-size: 0.76rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui-language-toolbar__copy p {
|
||||
margin: 0;
|
||||
font-size: 0.76rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-language-toolbar__toggle {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__button {
|
||||
min-width: 2.8rem;
|
||||
padding: 0.4rem 0.6rem;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 999px;
|
||||
background: #ffffff;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__button.complete {
|
||||
border-color: #c9d8c4;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__button.incomplete {
|
||||
border-color: #e8c8c2;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__button.active {
|
||||
background: #fff5b8;
|
||||
border-color: var(--color-brand);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui-choice-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@@ -329,6 +727,17 @@ select.ui-form-control {
|
||||
background: #dc2626;
|
||||
}
|
||||
|
||||
.ui-button--ghost-danger {
|
||||
background: var(--color-bg-card);
|
||||
border: 1px solid var(--color-border);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.ui-button--ghost-danger:hover:not(:disabled) {
|
||||
background: #fff0f0;
|
||||
border-color: #d9534f;
|
||||
}
|
||||
|
||||
.ui-pill,
|
||||
.ui-status-chip {
|
||||
display: inline-flex;
|
||||
@@ -344,6 +753,95 @@ select.ui-form-control {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ui-pill--neutral {
|
||||
background: var(--color-surface-muted);
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-pill--light {
|
||||
background: #f7f4e7;
|
||||
color: var(--color-neutral-900);
|
||||
}
|
||||
|
||||
.ui-pill--accent {
|
||||
background: #fff5b8;
|
||||
color: var(--color-text);
|
||||
border-color: #f1d65c;
|
||||
}
|
||||
|
||||
.ui-pill--soft {
|
||||
background: #f8f9fb;
|
||||
color: var(--color-neutral-900);
|
||||
}
|
||||
|
||||
.ui-stat-chip {
|
||||
min-width: 128px;
|
||||
padding: 0.75rem 0.9rem;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: linear-gradient(180deg, #fffdf5 0%, #ffffff 100%);
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.ui-stat-chip strong {
|
||||
font-size: 1.15rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ui-stat-chip span {
|
||||
font-size: 0.8rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.ui-banner {
|
||||
margin: 0;
|
||||
padding: 0.85rem 1rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-md);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ui-banner--error {
|
||||
color: #8a241d;
|
||||
background: #fff1f0;
|
||||
border-color: #f2c3bf;
|
||||
}
|
||||
|
||||
.ui-banner--success {
|
||||
color: #20613a;
|
||||
background: #eef9f1;
|
||||
border-color: #b7e3c4;
|
||||
}
|
||||
|
||||
.ui-subpanel {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-bg-card);
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
.ui-subpanel--soft {
|
||||
background: linear-gradient(180deg, #fcfcfb 0%, #f7f7f4 100%);
|
||||
}
|
||||
|
||||
.ui-subpanel--warm {
|
||||
border-radius: calc(var(--radius-lg) + 2px);
|
||||
padding: clamp(12px, 1.8vw, 18px);
|
||||
background: linear-gradient(180deg, #fcfbf8 0%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.ui-subpanel--elevated {
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
.ui-workspace-compact {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
|
||||
gap: var(--space-3);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.ui-status-chip--neutral {
|
||||
background: var(--color-surface-muted);
|
||||
}
|
||||
@@ -473,6 +971,49 @@ select.ui-form-control {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.ui-media-list {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.ui-media-item {
|
||||
display: grid;
|
||||
grid-template-columns: 168px minmax(0, 1fr);
|
||||
gap: var(--space-2);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 0.75rem;
|
||||
background: var(--color-bg-card);
|
||||
}
|
||||
|
||||
.ui-thumb {
|
||||
aspect-ratio: 16 / 10;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--color-neutral-200);
|
||||
}
|
||||
|
||||
.ui-thumb img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.ui-thumb--empty {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
text-align: center;
|
||||
color: var(--color-text-muted);
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
.ui-empty-state {
|
||||
margin: 0;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.ui-form-row {
|
||||
flex-direction: row;
|
||||
@@ -483,16 +1024,25 @@ select.ui-form-control {
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.ui-content-grid--split {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.ui-two-column-layout,
|
||||
.ui-split-workspace {
|
||||
.ui-split-workspace,
|
||||
.ui-workspace-compact {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.ui-form-row--three,
|
||||
.ui-choice-grid {
|
||||
.ui-choice-grid,
|
||||
.ui-form-grid--two,
|
||||
.ui-media-item {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
@@ -506,4 +1056,33 @@ select.ui-form-control {
|
||||
.ui-page-hero {
|
||||
padding: var(--space-6) 0;
|
||||
}
|
||||
|
||||
.ui-inline-actions {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.ui-language-toolbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.ui-language-toolbar__toggle {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.ui-file-picker {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.ui-file-picker__button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-nav-button {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user