mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
2134 lines
49 KiB
CSS
2134 lines
49 KiB
CSS
/*
|
||
* Sub-page styles — Skills / Systems / Craft / Templates index +
|
||
* detail layouts.
|
||
*
|
||
* Lives in a separate stylesheet (not `globals.css`) so the
|
||
* lockstep-with-`example.html` rule on the homepage stays intact.
|
||
* All tokens here come from the same Atelier Zero CSS custom
|
||
* properties defined in `globals.css` — keep this file focused
|
||
* on layout primitives the sub-pages need.
|
||
*/
|
||
|
||
/* ---------- shell adjustments ---------- */
|
||
|
||
body.sub-page {
|
||
/* sub-pages don't have a hero, so the nav can sit closer to the
|
||
* page top without the topbar strip pushing it down. */
|
||
background: var(--paper);
|
||
}
|
||
|
||
.sub-main {
|
||
/* Only set vertical padding here. The element also has the `.container`
|
||
* class which provides the responsive horizontal gutter; using the
|
||
* `padding` shorthand instead would zero out left/right and let
|
||
* content touch the screen edge on mobile (issue #review-fix-8). */
|
||
padding-top: 140px;
|
||
padding-bottom: 96px;
|
||
min-height: 60vh;
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.sub-main {
|
||
padding-top: 120px;
|
||
padding-bottom: 72px;
|
||
}
|
||
}
|
||
|
||
/* ---------- nav active state ---------- */
|
||
|
||
.nav-links a.is-active {
|
||
color: var(--ink);
|
||
}
|
||
.nav-links a.is-active::after {
|
||
content: '';
|
||
display: block;
|
||
height: 1.5px;
|
||
background: var(--coral);
|
||
margin-top: 4px;
|
||
border-radius: 2px;
|
||
}
|
||
|
||
/* ---------- breadcrumb ---------- */
|
||
|
||
.breadcrumb {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
align-items: center;
|
||
margin-bottom: 28px;
|
||
}
|
||
.breadcrumb a {
|
||
color: var(--ink-mute);
|
||
text-decoration: none;
|
||
border-bottom: 1px solid transparent;
|
||
transition: color 0.16s ease, border-color 0.16s ease;
|
||
}
|
||
.breadcrumb a:hover {
|
||
color: var(--ink);
|
||
border-bottom-color: var(--coral);
|
||
}
|
||
.breadcrumb span:not([aria-current]) { opacity: 0.5; }
|
||
.breadcrumb [aria-current] { color: var(--ink); }
|
||
|
||
/* ---------- catalog head (shared between index pages) ---------- */
|
||
|
||
.catalog-head {
|
||
max-width: 880px;
|
||
margin-bottom: 56px;
|
||
border-top: 1px solid var(--ink);
|
||
padding-top: 28px;
|
||
}
|
||
.catalog-head .label {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
display: inline-block;
|
||
margin-bottom: 18px;
|
||
}
|
||
.catalog-head .display {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: clamp(40px, 6vw, 72px);
|
||
line-height: 1.04;
|
||
letter-spacing: -0.022em;
|
||
color: var(--ink);
|
||
margin-bottom: 24px;
|
||
}
|
||
.catalog-head .display em {
|
||
font-style: italic;
|
||
font-weight: 600;
|
||
color: var(--coral);
|
||
}
|
||
.catalog-head .display .dot { color: var(--coral); }
|
||
.catalog-head .lead {
|
||
font-size: 17px;
|
||
line-height: 1.6;
|
||
color: var(--ink-soft);
|
||
max-width: 720px;
|
||
}
|
||
.catalog-head .lead code {
|
||
font-family: var(--mono);
|
||
font-size: 0.92em;
|
||
background: rgba(237, 111, 92, 0.08);
|
||
padding: 1px 6px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* ---------- filter strip ---------- */
|
||
|
||
.filter-strip {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 14px;
|
||
margin-bottom: 0;
|
||
padding: 22px 0;
|
||
border-top: 1px solid var(--line);
|
||
border-bottom: none;
|
||
/*
|
||
* When the user clicks an artifact-kind chip on a different
|
||
* /plugins/templates/<kind>/ page, the anchor `#filter-strip`
|
||
* lands here. The 96px margin keeps the sticky site nav from
|
||
* covering the chip rail and gives a breath of paper above the
|
||
* chips so the rail reads as a "still here" marker rather than
|
||
* snapping flush to the viewport edge.
|
||
*/
|
||
scroll-margin-top: 96px;
|
||
}
|
||
/*
|
||
* Adjacent strips share the single divider above the artifact-kind
|
||
* rail rather than drawing one each — keeps the kind + scene chip
|
||
* block reading as a single unit instead of stacked horizontal
|
||
* cuts. The grid below gets its own breathing-room margin so it
|
||
* doesn't slam straight into the last chip row.
|
||
*/
|
||
.filter-strip + .filter-strip {
|
||
border-top: 0;
|
||
padding-top: 6px;
|
||
}
|
||
.filter-strip + .tpl-grid,
|
||
.filter-strip + .catalog-grid {
|
||
margin-top: 36px;
|
||
}
|
||
.filter-group {
|
||
display: grid;
|
||
grid-template-columns: 100px 1fr;
|
||
gap: 18px;
|
||
align-items: baseline;
|
||
}
|
||
.filter-label {
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
}
|
||
.filter-group ul {
|
||
list-style: none;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 5px 12px;
|
||
border: 1px solid var(--line);
|
||
border-radius: 999px;
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.06em;
|
||
color: var(--ink);
|
||
background: rgba(255, 255, 255, 0.32);
|
||
transition: border-color 0.16s ease, color 0.16s ease;
|
||
text-decoration: none;
|
||
}
|
||
.chip:hover {
|
||
border-color: var(--coral);
|
||
color: var(--coral);
|
||
}
|
||
.chip-link {
|
||
cursor: pointer;
|
||
}
|
||
.chip-link:hover {
|
||
background: rgba(237, 111, 92, 0.06);
|
||
}
|
||
/*
|
||
* Active state for filter chips on the /plugins/templates/ rails. The
|
||
* chip pointing at the page the user is on swaps to a filled coral
|
||
* background so the rail keeps reading as a "you are here" marker
|
||
* rather than a row of identical buttons.
|
||
*/
|
||
.chip-link.is-active,
|
||
.chip-link[aria-current='page'] {
|
||
background: var(--coral);
|
||
border-color: var(--coral);
|
||
color: #fff;
|
||
}
|
||
.chip-link.is-active .chip-num,
|
||
.chip-link[aria-current='page'] .chip-num {
|
||
color: rgba(255, 255, 255, 0.75);
|
||
}
|
||
.chip-link.is-active:hover,
|
||
.chip-link[aria-current='page']:hover {
|
||
background: var(--coral);
|
||
color: #fff;
|
||
}
|
||
.chip-num {
|
||
color: var(--ink-mute);
|
||
font-size: 10px;
|
||
}
|
||
|
||
/* breadcrumb active leaf + filter-clear back-link share styling so
|
||
* faceted views feel coherent with the breadcrumb above. */
|
||
.breadcrumb .crumb-active {
|
||
color: var(--ink);
|
||
opacity: 1;
|
||
}
|
||
.filter-clear {
|
||
margin-top: 18px;
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
}
|
||
.filter-clear a {
|
||
color: var(--ink-mute);
|
||
text-decoration: none;
|
||
border-bottom: 1px solid transparent;
|
||
transition: color 0.16s ease, border-color 0.16s ease;
|
||
}
|
||
.filter-clear a:hover {
|
||
color: var(--coral);
|
||
border-bottom-color: var(--coral);
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.filter-group { grid-template-columns: 1fr; gap: 8px; }
|
||
}
|
||
|
||
/* ---------- featured strip (skills index) ---------- */
|
||
|
||
.featured-strip {
|
||
margin-bottom: 56px;
|
||
}
|
||
.strip-title {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
margin-bottom: 16px;
|
||
}
|
||
.featured-grid {
|
||
list-style: none;
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 16px;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.featured-card {
|
||
position: relative;
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
transition: border-color 0.16s ease, transform 0.16s ease;
|
||
overflow: hidden;
|
||
}
|
||
.featured-card:hover {
|
||
border-color: var(--coral);
|
||
transform: translateY(-2px);
|
||
}
|
||
.featured-card a {
|
||
display: block;
|
||
padding: 0;
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
}
|
||
.featured-card a > * + * {
|
||
margin-left: 24px;
|
||
margin-right: 24px;
|
||
}
|
||
.featured-card .featured-num { margin-top: 18px; }
|
||
.featured-card p { margin-bottom: 12px; }
|
||
.featured-card .meta-tag { margin-bottom: 22px; }
|
||
.featured-thumb {
|
||
display: block;
|
||
margin: 0;
|
||
aspect-ratio: 16 / 10;
|
||
background: var(--paper-warm);
|
||
border-bottom: 1px solid var(--line-soft);
|
||
overflow: hidden;
|
||
}
|
||
.featured-thumb img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
object-position: top center;
|
||
display: block;
|
||
transition: transform 0.5s ease;
|
||
}
|
||
.featured-card:hover .featured-thumb img { transform: scale(1.02); }
|
||
.featured-thumb-empty {
|
||
background:
|
||
repeating-linear-gradient(
|
||
135deg,
|
||
var(--paper-dark),
|
||
var(--paper-dark) 10px,
|
||
var(--paper-warm) 10px,
|
||
var(--paper-warm) 20px
|
||
);
|
||
}
|
||
.featured-num {
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--coral);
|
||
display: block;
|
||
margin-bottom: 12px;
|
||
}
|
||
.featured-name {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 22px;
|
||
line-height: 1.2;
|
||
letter-spacing: -0.01em;
|
||
color: var(--ink);
|
||
display: block;
|
||
margin-bottom: 8px;
|
||
}
|
||
.featured-card p {
|
||
color: var(--ink-soft);
|
||
font-size: 13px;
|
||
line-height: 1.5;
|
||
/* Only set bottom margin here. Horizontal margin is owned by the
|
||
* `.featured-card a > * + *` rule above (24px both sides); using
|
||
* the `margin: ...` shorthand instead would clobber that to 0 and
|
||
* the description text would bleed against the card edge. Same
|
||
* fragility template-summary fixed in #2600. */
|
||
margin-bottom: 12px;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 3;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
|
||
@media (max-width: 980px) {
|
||
.featured-grid { grid-template-columns: repeat(2, 1fr); }
|
||
}
|
||
@media (max-width: 600px) {
|
||
.featured-grid { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
/* ---------- catalog grid (linear list, used by skills + craft + templates) ---------- */
|
||
|
||
.catalog-grid {
|
||
margin-top: 16px;
|
||
}
|
||
.catalog-grid ol,
|
||
.catalog-grid ul {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
border-top: 1px solid var(--line);
|
||
}
|
||
.catalog-row {
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
.catalog-row a {
|
||
display: grid;
|
||
grid-template-columns: 60px 1fr auto auto;
|
||
gap: 24px;
|
||
align-items: center;
|
||
/*
|
||
* Horizontal 24px lockstep with the rest of the catalog tile
|
||
* families (featured-card / template-card / system-card / source-card).
|
||
* Hover used to push from 0 → 12px which produced a visible
|
||
* jolt; staying at 24 base + only changing background on hover
|
||
* keeps the row composition steady.
|
||
*/
|
||
padding: 22px 24px;
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
}
|
||
.catalog-row-skill a {
|
||
grid-template-columns: 60px 130px 1fr auto auto;
|
||
}
|
||
.catalog-row a:hover {
|
||
background: var(--paper-warm);
|
||
}
|
||
.catalog-row a:hover .row-arrow { color: var(--coral); transform: translateX(4px); }
|
||
|
||
.row-thumb {
|
||
display: block;
|
||
width: 130px;
|
||
aspect-ratio: 16 / 10;
|
||
border: 1px solid var(--line-soft);
|
||
background: var(--paper-warm);
|
||
overflow: hidden;
|
||
}
|
||
.row-thumb img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
object-position: top center;
|
||
display: block;
|
||
}
|
||
.row-thumb-empty {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
background:
|
||
repeating-linear-gradient(
|
||
135deg,
|
||
var(--paper-dark),
|
||
var(--paper-dark) 8px,
|
||
var(--paper-warm) 8px,
|
||
var(--paper-warm) 16px
|
||
);
|
||
}
|
||
|
||
.row-index {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.16em;
|
||
color: var(--ink-mute);
|
||
}
|
||
.row-body {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
min-width: 0;
|
||
}
|
||
.row-name {
|
||
font-family: var(--sans);
|
||
font-weight: 600;
|
||
font-size: 17px;
|
||
letter-spacing: -0.005em;
|
||
color: var(--ink);
|
||
}
|
||
.row-desc {
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
color: var(--ink-soft);
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
.row-meta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
max-width: 320px;
|
||
}
|
||
.row-arrow {
|
||
font-family: var(--mono);
|
||
color: var(--ink-faint);
|
||
transition: color 0.16s ease, transform 0.16s ease;
|
||
}
|
||
|
||
.meta-tag {
|
||
display: inline-block;
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
border: 1px solid var(--line);
|
||
padding: 3px 9px;
|
||
border-radius: 999px;
|
||
}
|
||
.meta-tag.muted {
|
||
color: var(--ink-mute);
|
||
border-color: var(--line-soft);
|
||
}
|
||
.meta-tag.coral {
|
||
color: var(--coral);
|
||
border-color: rgba(237, 111, 92, 0.4);
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.catalog-row a,
|
||
.catalog-row-skill a {
|
||
grid-template-columns: 36px 1fr auto;
|
||
gap: 14px;
|
||
/* Keep a real horizontal gutter at narrow widths so the row body
|
||
* doesn't bleed against the card edge. The previous `0` was a
|
||
* holdover from when hover padding was the only horizontal inset. */
|
||
padding: 18px 20px;
|
||
}
|
||
.row-meta { display: none; }
|
||
.row-thumb { display: none; }
|
||
.row-arrow { font-size: 14px; }
|
||
}
|
||
|
||
/* ---------- template grid ---------- */
|
||
|
||
.template-grid ul {
|
||
list-style: none;
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 20px;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.template-card {
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
transition: border-color 0.16s ease, transform 0.16s ease;
|
||
overflow: hidden;
|
||
}
|
||
.template-card:hover {
|
||
border-color: var(--coral);
|
||
transform: translateY(-2px);
|
||
}
|
||
.template-card a {
|
||
display: block;
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
}
|
||
.template-card a > .meta-tag,
|
||
.template-card a > .template-name,
|
||
.template-card a > .template-summary,
|
||
.template-card a > .template-meta-line {
|
||
margin-left: 24px;
|
||
margin-right: 24px;
|
||
}
|
||
.template-card a > .meta-tag {
|
||
display: inline-block;
|
||
margin-top: 16px;
|
||
}
|
||
.template-thumb {
|
||
display: block;
|
||
aspect-ratio: 16 / 10;
|
||
background: var(--paper-warm);
|
||
border-bottom: 1px solid var(--line-soft);
|
||
overflow: hidden;
|
||
}
|
||
.template-thumb img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
object-position: top center;
|
||
display: block;
|
||
transition: transform 0.5s ease;
|
||
}
|
||
.template-card:hover .template-thumb img { transform: scale(1.02); }
|
||
.template-thumb-empty {
|
||
background:
|
||
repeating-linear-gradient(
|
||
135deg,
|
||
var(--paper-dark),
|
||
var(--paper-dark) 10px,
|
||
var(--paper-warm) 10px,
|
||
var(--paper-warm) 20px
|
||
);
|
||
}
|
||
.template-name {
|
||
display: block;
|
||
margin-top: 10px;
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 22px;
|
||
line-height: 1.2;
|
||
letter-spacing: -0.01em;
|
||
color: var(--ink);
|
||
}
|
||
.template-summary {
|
||
/* Horizontal padding (24px) is owned by the group rule on
|
||
* `.template-card a > .template-summary` above; this rule only sets
|
||
* top/bottom rhythm so siblings stay in lockstep. */
|
||
margin-top: 8px;
|
||
margin-bottom: 20px;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
color: var(--ink-soft);
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 3;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
.template-meta-line {
|
||
display: block;
|
||
/* Negative top tugs this row up against the summary; horizontal owned
|
||
* by the group rule above. */
|
||
margin-top: -10px;
|
||
margin-bottom: 20px;
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.template-grid ul { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
/* ---------- systems grid ---------- */
|
||
|
||
.systems-grid ul {
|
||
list-style: none;
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 18px;
|
||
padding: 0;
|
||
margin: 0;
|
||
border-top: none;
|
||
}
|
||
.system-card {
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
transition: border-color 0.16s ease, transform 0.16s ease;
|
||
}
|
||
.system-card:hover {
|
||
border-color: var(--coral);
|
||
transform: translateY(-2px);
|
||
}
|
||
.system-card a {
|
||
display: block;
|
||
padding: 18px 24px 22px;
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
}
|
||
.system-swatches {
|
||
display: flex;
|
||
gap: 0;
|
||
height: 28px;
|
||
margin-bottom: 14px;
|
||
border: 1px solid var(--line-soft);
|
||
}
|
||
.system-swatches .swatch {
|
||
flex: 1;
|
||
display: block;
|
||
}
|
||
.system-swatches .swatch.placeholder {
|
||
background: repeating-linear-gradient(
|
||
45deg,
|
||
var(--paper-dark),
|
||
var(--paper-dark) 6px,
|
||
var(--paper-warm) 6px,
|
||
var(--paper-warm) 12px
|
||
);
|
||
}
|
||
.system-name {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 20px;
|
||
line-height: 1.2;
|
||
display: block;
|
||
margin-bottom: 4px;
|
||
color: var(--ink);
|
||
}
|
||
.system-cat {
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
display: block;
|
||
margin-bottom: 10px;
|
||
}
|
||
.system-tagline {
|
||
font-size: 13px;
|
||
line-height: 1.5;
|
||
color: var(--ink-soft);
|
||
margin: 0;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 3;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
|
||
@media (max-width: 980px) {
|
||
.systems-grid ul { grid-template-columns: repeat(2, 1fr); }
|
||
}
|
||
@media (max-width: 600px) {
|
||
.systems-grid ul { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
/* ---------- detail pages ---------- */
|
||
|
||
.detail {
|
||
max-width: 880px;
|
||
}
|
||
.detail-head {
|
||
border-top: 1px solid var(--ink);
|
||
padding-top: 28px;
|
||
margin-bottom: 48px;
|
||
}
|
||
.detail-head .label {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
display: inline-block;
|
||
margin-bottom: 18px;
|
||
}
|
||
.detail-head .label .ix {
|
||
color: var(--coral);
|
||
margin-left: 6px;
|
||
}
|
||
.detail-head .display {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: clamp(36px, 5vw, 60px);
|
||
line-height: 1.05;
|
||
letter-spacing: -0.02em;
|
||
color: var(--ink);
|
||
margin-bottom: 22px;
|
||
}
|
||
.detail-head .display .dot { color: var(--coral); }
|
||
.detail-head .lead {
|
||
font-size: 17px;
|
||
line-height: 1.6;
|
||
color: var(--ink-soft);
|
||
margin-bottom: 28px;
|
||
max-width: 720px;
|
||
}
|
||
|
||
.detail-actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
}
|
||
|
||
.detail-preview {
|
||
margin: 0 0 48px;
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
overflow: hidden;
|
||
}
|
||
.detail-preview img {
|
||
width: 100%;
|
||
height: auto;
|
||
display: block;
|
||
border-bottom: 1px solid var(--line-soft);
|
||
}
|
||
.detail-preview figcaption {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.06em;
|
||
color: var(--ink-mute);
|
||
padding: 12px 16px;
|
||
}
|
||
.detail-preview figcaption code {
|
||
background: rgba(237, 111, 92, 0.08);
|
||
padding: 1px 6px;
|
||
border-radius: 3px;
|
||
color: var(--ink);
|
||
}
|
||
|
||
/* `btn` styles already exist in globals.css; the detail-actions only
|
||
* positions them. */
|
||
|
||
.detail-meta {
|
||
display: grid;
|
||
grid-template-columns: 120px 1fr;
|
||
gap: 8px 24px;
|
||
padding: 24px 0;
|
||
margin-bottom: 40px;
|
||
border-top: 1px solid var(--line);
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
.detail-meta dt {
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
margin: 0;
|
||
}
|
||
.detail-meta dd {
|
||
margin: 0;
|
||
font-family: var(--sans);
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
color: var(--ink);
|
||
}
|
||
|
||
.detail-block {
|
||
margin-bottom: 48px;
|
||
}
|
||
.detail-block h2 {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 22px;
|
||
letter-spacing: -0.005em;
|
||
color: var(--ink);
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
/*
|
||
* Inline-rendered SKILL.md body for instruction-kind skills. We strip
|
||
* the SKILL.md H1 (already on the page as the detail header) and the
|
||
* `> Curated from @author.` blockquote (already exposed in attribution),
|
||
* but otherwise let Astro's standard markdown pipeline take over so
|
||
* tables, code blocks, lists, etc. all render with the existing site
|
||
* typography.
|
||
*/
|
||
.detail-md > h1:first-child,
|
||
.detail-md > blockquote:first-of-type {
|
||
display: none;
|
||
}
|
||
.detail-md p,
|
||
.detail-md ul,
|
||
.detail-md ol {
|
||
font-size: 16px;
|
||
line-height: 1.65;
|
||
color: var(--ink);
|
||
max-width: 720px;
|
||
}
|
||
.detail-md p,
|
||
.detail-md ul,
|
||
.detail-md ol,
|
||
.detail-md pre,
|
||
.detail-md table {
|
||
margin: 0 0 18px;
|
||
}
|
||
.detail-md h3 {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 18px;
|
||
margin: 28px 0 8px;
|
||
color: var(--ink);
|
||
}
|
||
.detail-md h4 {
|
||
font-family: var(--mono);
|
||
font-size: 12px;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
margin: 24px 0 6px;
|
||
}
|
||
.detail-md ul,
|
||
.detail-md ol {
|
||
padding-left: 1.4em;
|
||
}
|
||
.detail-md li {
|
||
margin-bottom: 4px;
|
||
}
|
||
.detail-md code {
|
||
font-family: var(--mono);
|
||
font-size: 13px;
|
||
background: var(--paper-dark, var(--paper-warm));
|
||
border: 1px solid var(--line-soft);
|
||
border-radius: 4px;
|
||
padding: 1px 6px;
|
||
}
|
||
.detail-md pre {
|
||
background: var(--paper-dark, var(--paper-warm));
|
||
border: 1px solid var(--line-soft);
|
||
padding: 12px 14px;
|
||
overflow-x: auto;
|
||
font-family: var(--mono);
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
}
|
||
.detail-md pre code {
|
||
background: transparent;
|
||
border: 0;
|
||
padding: 0;
|
||
}
|
||
.detail-md a {
|
||
color: var(--ink);
|
||
border-bottom: 1px solid var(--ink-mute);
|
||
}
|
||
.detail-md a:hover {
|
||
color: var(--coral);
|
||
border-bottom-color: var(--coral);
|
||
}
|
||
.detail-md blockquote {
|
||
margin: 0 0 18px;
|
||
padding-left: 14px;
|
||
border-left: 2px solid var(--line);
|
||
color: var(--ink-mute);
|
||
font-style: italic;
|
||
}
|
||
.block-lead {
|
||
color: var(--ink-soft);
|
||
font-size: 15px;
|
||
line-height: 1.55;
|
||
margin-bottom: 20px;
|
||
max-width: 680px;
|
||
}
|
||
|
||
.trigger-list {
|
||
list-style: none;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.trigger-list li code {
|
||
display: inline-block;
|
||
font-family: var(--mono);
|
||
font-size: 12px;
|
||
background: rgba(237, 111, 92, 0.08);
|
||
border: 1px solid rgba(237, 111, 92, 0.22);
|
||
color: var(--ink);
|
||
padding: 4px 10px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.example-prompt {
|
||
font-family: var(--mono);
|
||
font-size: 13px;
|
||
line-height: 1.55;
|
||
background: var(--paper-warm);
|
||
border-left: 3px solid var(--coral);
|
||
padding: 18px 20px;
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
color: var(--ink);
|
||
}
|
||
|
||
.atmosphere {
|
||
font-family: var(--serif);
|
||
font-style: italic;
|
||
font-size: 18px;
|
||
line-height: 1.6;
|
||
color: var(--ink);
|
||
max-width: 720px;
|
||
border-left: 3px solid var(--coral);
|
||
padding-left: 20px;
|
||
}
|
||
|
||
.palette-row {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16px;
|
||
}
|
||
.palette-cell {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
align-items: flex-start;
|
||
}
|
||
.palette-cell .swatch {
|
||
width: 80px;
|
||
height: 80px;
|
||
border: 1px solid var(--line);
|
||
border-radius: 4px;
|
||
}
|
||
.palette-cell code {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.05em;
|
||
color: var(--ink);
|
||
}
|
||
|
||
.related-grid {
|
||
list-style: none;
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 14px;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.related-grid li {
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
transition: border-color 0.16s ease, transform 0.16s ease;
|
||
}
|
||
.related-grid li:hover { border-color: var(--coral); transform: translateY(-2px); }
|
||
.related-grid a {
|
||
display: block;
|
||
padding: 18px;
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
}
|
||
.related-name {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 18px;
|
||
letter-spacing: -0.005em;
|
||
display: block;
|
||
margin-bottom: 6px;
|
||
color: var(--ink);
|
||
}
|
||
.related-desc {
|
||
font-size: 13px;
|
||
line-height: 1.5;
|
||
color: var(--ink-soft);
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
margin-bottom: 8px;
|
||
}
|
||
.related-meta {
|
||
display: flex;
|
||
gap: 6px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.related-grid { grid-template-columns: 1fr; }
|
||
.detail-meta { grid-template-columns: 1fr; gap: 6px 0; }
|
||
.detail-meta dt { padding-top: 8px; }
|
||
.detail-meta dd { padding-bottom: 8px; border-bottom: 1px solid var(--line-soft); }
|
||
}
|
||
|
||
/* ---------- sub-page footer ---------- */
|
||
|
||
.sub-footer {
|
||
border-top: 1px solid var(--ink);
|
||
background: var(--paper);
|
||
padding: 60px 0 32px;
|
||
margin-top: 96px;
|
||
}
|
||
.sub-footer-grid {
|
||
display: grid;
|
||
grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr;
|
||
gap: 40px;
|
||
margin-bottom: 36px;
|
||
}
|
||
@media (max-width: 1080px) {
|
||
/* At medium widths, drop to a 3-column grid (brand + two columns
|
||
per row, since `.sub-footer-brand` carries no `grid-column` span)
|
||
so no column collapses to a single line of unrecognizable text.
|
||
With 5 children that flows as: row 1 = brand · Products · Plugins,
|
||
row 2 = Resources · Connect · empty cell. */
|
||
.sub-footer-grid { grid-template-columns: 1.6fr repeat(2, 1fr); }
|
||
}
|
||
.sub-footer-brand .brand {
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
font-family: var(--sans);
|
||
font-weight: 600;
|
||
font-size: 17px;
|
||
}
|
||
.sub-footer-brand p {
|
||
margin-top: 16px;
|
||
color: var(--ink-soft);
|
||
font-size: 14px;
|
||
line-height: 1.55;
|
||
max-width: 480px;
|
||
}
|
||
.sub-footer-col h5 {
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
margin-bottom: 14px;
|
||
font-weight: 500;
|
||
}
|
||
.sub-footer-col ul {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 9px;
|
||
}
|
||
.sub-footer-col a {
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
font-size: 14px;
|
||
transition: color 0.16s ease;
|
||
}
|
||
.sub-footer-col a:hover { color: var(--coral); }
|
||
.sub-footer-bottom {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
padding-top: 24px;
|
||
border-top: 1px solid var(--line-soft);
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.sub-footer-grid { grid-template-columns: 1fr; gap: 32px; }
|
||
.sub-footer { padding: 40px 0 24px; }
|
||
}
|
||
|
||
/* =========================================================
|
||
* SEO landing pages — /official/, /quickstart/, /compare/,
|
||
* /alternatives/claude-design/, /agents/
|
||
* =========================================================
|
||
*
|
||
* Shared layout primitives for the high-intent, mostly-textual
|
||
* pages added in growth/seo-opendesigner-analysis.md. These reuse
|
||
* Atelier Zero tokens; they avoid the editorial side rails and
|
||
* full hero, since these pages are query-legible first.
|
||
*/
|
||
.info-page {
|
||
max-width: 920px;
|
||
}
|
||
.info-page .info-section + .info-section { margin-top: 64px; }
|
||
.info-page h2 {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: clamp(26px, 3.4vw, 36px);
|
||
letter-spacing: -0.012em;
|
||
color: var(--ink);
|
||
margin: 0 0 14px;
|
||
}
|
||
.info-page h2 em {
|
||
font-style: italic;
|
||
font-weight: 600;
|
||
color: var(--coral);
|
||
}
|
||
.info-page h3 {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 20px;
|
||
letter-spacing: -0.005em;
|
||
color: var(--ink);
|
||
margin: 28px 0 10px;
|
||
}
|
||
.info-page p {
|
||
font-family: var(--sans);
|
||
font-size: 15.5px;
|
||
line-height: 1.7;
|
||
color: var(--ink-soft);
|
||
margin: 0 0 14px;
|
||
max-width: 70ch;
|
||
}
|
||
.info-page p code,
|
||
.info-page li code {
|
||
font-family: var(--mono);
|
||
font-size: 0.92em;
|
||
background: rgba(237, 111, 92, 0.08);
|
||
padding: 1px 6px;
|
||
border-radius: 4px;
|
||
color: var(--ink);
|
||
}
|
||
.info-page ul,
|
||
.info-page ol {
|
||
margin: 0 0 18px;
|
||
padding-left: 1.4em;
|
||
color: var(--ink-soft);
|
||
}
|
||
.info-page li {
|
||
font-family: var(--sans);
|
||
font-size: 15px;
|
||
line-height: 1.7;
|
||
margin-bottom: 6px;
|
||
}
|
||
.info-page strong { color: var(--ink); }
|
||
.info-page a.inline-link {
|
||
color: var(--ink);
|
||
text-decoration: none;
|
||
border-bottom: 1px solid var(--coral);
|
||
}
|
||
.info-page a.inline-link:hover { color: var(--coral); }
|
||
|
||
/* Source-of-truth "official links" card used on /official/ and
|
||
* elsewhere we need to lead with the canonical surface. */
|
||
.source-card {
|
||
border: 1px solid var(--ink);
|
||
background: var(--paper-warm);
|
||
padding: 24px;
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 14px 28px;
|
||
margin: 0 0 32px;
|
||
}
|
||
.source-card a {
|
||
display: grid;
|
||
grid-template-columns: 1fr auto;
|
||
gap: 8px;
|
||
padding: 8px 0;
|
||
border-bottom: 1px solid var(--line-soft);
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
font-family: var(--sans);
|
||
font-size: 14.5px;
|
||
transition: color 0.16s ease;
|
||
}
|
||
.source-card a:hover { color: var(--coral); }
|
||
.source-card a span.label {
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
}
|
||
.source-card a span.arrow { color: var(--coral); }
|
||
|
||
@media (max-width: 720px) {
|
||
.source-card { grid-template-columns: 1fr; padding: 18px 20px; }
|
||
}
|
||
|
||
/* Comparison table for /compare/ and /alternatives/claude-design/. */
|
||
.compare-table-wrap {
|
||
overflow-x: auto;
|
||
margin: 0 0 32px;
|
||
border: 1px solid var(--line);
|
||
}
|
||
.compare-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-family: var(--sans);
|
||
font-size: 14px;
|
||
min-width: 720px;
|
||
}
|
||
.compare-table th,
|
||
.compare-table td {
|
||
text-align: left;
|
||
padding: 14px 16px;
|
||
border-bottom: 1px solid var(--line);
|
||
vertical-align: top;
|
||
}
|
||
.compare-table thead th {
|
||
background: var(--paper-warm);
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
}
|
||
.compare-table tbody tr:last-child td { border-bottom: none; }
|
||
.compare-table tbody th {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 14.5px;
|
||
color: var(--ink);
|
||
width: 28%;
|
||
}
|
||
.compare-table td.yes { color: var(--ink); }
|
||
.compare-table td.no { color: var(--ink-faint); }
|
||
.compare-table td .check { color: var(--coral); font-weight: 600; margin-right: 6px; }
|
||
|
||
/* Code block for /quickstart/ command sequences. */
|
||
.code-block {
|
||
display: block;
|
||
font-family: var(--mono);
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
background: var(--ink);
|
||
color: var(--paper);
|
||
padding: 18px 22px;
|
||
margin: 0 0 18px;
|
||
overflow-x: auto;
|
||
white-space: pre;
|
||
border-radius: 2px;
|
||
}
|
||
.code-block .prompt { color: var(--coral); }
|
||
.code-block .comment { color: rgba(255, 255, 255, 0.5); }
|
||
|
||
/* Agent / comparison cards grid used on /compare/, /agents/. */
|
||
.agent-grid,
|
||
.compare-grid {
|
||
list-style: none;
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 16px;
|
||
padding: 0;
|
||
margin: 0 0 32px;
|
||
}
|
||
.agent-card,
|
||
.compare-card {
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
padding: 22px 24px;
|
||
transition: border-color 0.16s ease, transform 0.16s ease;
|
||
}
|
||
.agent-card:hover,
|
||
.compare-card:hover { border-color: var(--coral); transform: translateY(-2px); }
|
||
.agent-card h3,
|
||
.compare-card h3 { margin: 0 0 10px; }
|
||
.agent-card p,
|
||
.compare-card p {
|
||
margin: 0 0 12px;
|
||
font-size: 14.5px;
|
||
color: var(--ink-soft);
|
||
}
|
||
.agent-card a,
|
||
.compare-card a {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
text-decoration: none;
|
||
border-bottom: 1px solid var(--coral);
|
||
}
|
||
.agent-card a:hover,
|
||
.compare-card a:hover { color: var(--coral); }
|
||
|
||
@media (max-width: 720px) {
|
||
.agent-grid,
|
||
.compare-grid { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
/* In-page TOC for the longer alternative + compare pages. */
|
||
.info-toc {
|
||
border-top: 1px solid var(--line);
|
||
border-bottom: 1px solid var(--line);
|
||
padding: 18px 0;
|
||
margin: 0 0 40px;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 18px;
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
}
|
||
.info-toc span {
|
||
color: var(--ink-mute);
|
||
}
|
||
.info-toc a {
|
||
color: var(--ink);
|
||
text-decoration: none;
|
||
border-bottom: 1px solid transparent;
|
||
transition: border-color 0.16s ease;
|
||
}
|
||
.info-toc a:hover { border-bottom-color: var(--coral); }
|
||
|
||
/* Closing CTA strip — used at the bottom of /quickstart/, /agents/,
|
||
* /alternatives/claude-design/. Gives the documentation-heavy SEO
|
||
* pages a concrete exit point: Star · Download · Discord. */
|
||
.info-cta {
|
||
margin-top: 56px;
|
||
padding: 36px 0 28px;
|
||
border-top: 1px solid var(--ink);
|
||
display: grid;
|
||
grid-template-columns: 1.4fr 1fr;
|
||
gap: 32px;
|
||
align-items: end;
|
||
}
|
||
.info-cta h2 {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: clamp(26px, 3.4vw, 36px);
|
||
letter-spacing: -0.012em;
|
||
color: var(--ink);
|
||
margin: 0 0 8px;
|
||
}
|
||
.info-cta h2 em {
|
||
font-style: italic;
|
||
color: var(--coral);
|
||
}
|
||
.info-cta p {
|
||
margin: 0;
|
||
color: var(--ink-soft);
|
||
font-size: 15px;
|
||
line-height: 1.6;
|
||
}
|
||
.info-cta-actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
justify-content: flex-end;
|
||
}
|
||
.info-cta-actions .btn {
|
||
white-space: nowrap;
|
||
}
|
||
.info-cta-meta {
|
||
grid-column: 1 / -1;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 18px;
|
||
padding-top: 18px;
|
||
margin-top: 8px;
|
||
border-top: 1px solid var(--line);
|
||
font-family: var(--mono);
|
||
font-size: 10.5px;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-faint);
|
||
}
|
||
.info-cta-meta .stamp {
|
||
color: var(--coral);
|
||
font-weight: 600;
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.info-cta {
|
||
grid-template-columns: 1fr;
|
||
gap: 20px;
|
||
}
|
||
.info-cta-actions {
|
||
justify-content: flex-start;
|
||
}
|
||
}
|
||
|
||
/* TL;DR / Summary card. */
|
||
.tldr-card {
|
||
border-left: 3px solid var(--coral);
|
||
padding: 14px 0 14px 20px;
|
||
margin: 0 0 32px;
|
||
}
|
||
.tldr-card h3 {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--coral);
|
||
margin: 0 0 8px;
|
||
}
|
||
.tldr-card p {
|
||
font-family: var(--serif);
|
||
font-size: 18px;
|
||
line-height: 1.5;
|
||
color: var(--ink);
|
||
margin: 0;
|
||
max-width: none;
|
||
}
|
||
|
||
|
||
/* =========================================================
|
||
* Skill / template detail page: live preview + share row
|
||
* =========================================================
|
||
*
|
||
* `details > summary` toggles an iframe that renders the canonical
|
||
* `example.html` (or `preview.html` for live-artifacts). The frame
|
||
* is loaded lazily — click the summary, that's when the network
|
||
* request goes out.
|
||
*/
|
||
/*
|
||
* Click-to-expand interactive preview. The `<summary>` IS the
|
||
* thumbnail — when collapsed, users see a normal preview image; on
|
||
* hover the overlay reveals "Click for live preview ↗"; on click the
|
||
* details element opens, swapping the summary out for an iframe of
|
||
* the canonical example.html. The iframe's `loading="lazy"` plus the
|
||
* fact that `<details>` only renders content on open means the
|
||
* network request fires only when the user actually wants the live
|
||
* view.
|
||
*/
|
||
.detail-preview-live {
|
||
display: block;
|
||
}
|
||
.detail-preview-live > summary {
|
||
cursor: pointer;
|
||
list-style: none;
|
||
display: block;
|
||
margin: 0;
|
||
padding: 0;
|
||
border: 0;
|
||
background: transparent;
|
||
}
|
||
.detail-preview-live > summary::-webkit-details-marker { display: none; }
|
||
.detail-preview-thumb-trigger {
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.detail-preview-thumb-trigger img {
|
||
display: block;
|
||
width: 100%;
|
||
height: auto;
|
||
transition: transform 0.4s ease;
|
||
}
|
||
.detail-preview-thumb-trigger:hover img,
|
||
.detail-preview-thumb-trigger:focus-visible img {
|
||
transform: scale(1.015);
|
||
}
|
||
.detail-preview-thumb-overlay {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(21, 20, 15, 0);
|
||
transition: background 0.18s ease;
|
||
pointer-events: none;
|
||
}
|
||
.detail-preview-thumb-trigger:hover .detail-preview-thumb-overlay,
|
||
.detail-preview-thumb-trigger:focus-visible .detail-preview-thumb-overlay {
|
||
background: rgba(21, 20, 15, 0.42);
|
||
}
|
||
.detail-preview-thumb-cta {
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
color: var(--paper);
|
||
background: var(--coral);
|
||
padding: 10px 18px;
|
||
border-radius: 999px;
|
||
opacity: 0;
|
||
transform: translateY(6px);
|
||
transition: opacity 0.18s ease, transform 0.18s ease;
|
||
}
|
||
.detail-preview-thumb-trigger:hover .detail-preview-thumb-cta,
|
||
.detail-preview-thumb-trigger:focus-visible .detail-preview-thumb-cta {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
/* Once expanded, hide the summary so the iframe takes its place. */
|
||
.detail-preview-live[open] > summary { display: none; }
|
||
.detail-preview-frame-wrap {
|
||
position: relative;
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
aspect-ratio: 16 / 10;
|
||
overflow: hidden;
|
||
}
|
||
.detail-preview-frame {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
border: 0;
|
||
background: white;
|
||
}
|
||
.detail-preview-popout {
|
||
position: absolute;
|
||
top: 12px;
|
||
right: 12px;
|
||
font-family: var(--mono);
|
||
font-size: 10.5px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
background: var(--paper);
|
||
border: 1px solid currentColor;
|
||
padding: 6px 12px;
|
||
border-radius: 999px;
|
||
text-decoration: none;
|
||
transition: background 0.12s ease, color 0.12s ease;
|
||
}
|
||
.detail-preview-popout:hover {
|
||
background: var(--ink);
|
||
color: var(--paper);
|
||
}
|
||
|
||
/*
|
||
* Share dialog — replaces the previous inline 6-button row. The
|
||
* trigger is a `Share ↗` button inside `.detail-actions` (so it has
|
||
* visual weight equal to the primary CTAs); clicking opens a
|
||
* `<dialog>` with the canonical share copy ready to copy + a row of
|
||
* platform jump buttons that just open the vendor's compose page.
|
||
*
|
||
* The copy-then-paste flow works around platform pre-fill limits:
|
||
* LinkedIn / Facebook ignore `text` params, X truncates Chinese
|
||
* unpredictably, Reddit's title is title-only. Copy-then-paste is
|
||
* uniformly reliable.
|
||
*/
|
||
.detail-share-dialog {
|
||
border: 1px solid var(--ink);
|
||
background: var(--paper);
|
||
color: var(--ink);
|
||
width: min(540px, calc(100vw - 32px));
|
||
padding: 0;
|
||
border-radius: 4px;
|
||
box-shadow: 0 32px 80px rgba(21, 20, 15, 0.32);
|
||
}
|
||
.detail-share-dialog::backdrop {
|
||
background: rgba(21, 20, 15, 0.42);
|
||
}
|
||
.detail-share-dialog-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 14px;
|
||
padding: 24px 28px 28px;
|
||
margin: 0;
|
||
}
|
||
.detail-share-dialog-head {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 16px;
|
||
margin: 0;
|
||
}
|
||
.detail-share-dialog-head h2 {
|
||
font-family: var(--serif);
|
||
font-weight: 600;
|
||
font-size: 22px;
|
||
margin: 0;
|
||
}
|
||
.detail-share-dialog-close {
|
||
width: 30px;
|
||
height: 30px;
|
||
border: 1px solid var(--line);
|
||
background: transparent;
|
||
border-radius: 50%;
|
||
font-size: 18px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
color: var(--ink-mute);
|
||
transition: color 0.12s ease, border-color 0.12s ease;
|
||
}
|
||
.detail-share-dialog-close:hover { color: var(--coral); border-color: var(--coral); }
|
||
.detail-share-dialog-lead {
|
||
margin: 0;
|
||
font-size: 13px;
|
||
line-height: 1.5;
|
||
color: var(--ink-mute);
|
||
}
|
||
.detail-share-dialog-text {
|
||
width: 100%;
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
padding: 12px 14px;
|
||
font-family: var(--sans);
|
||
font-size: 13px;
|
||
line-height: 1.55;
|
||
color: var(--ink);
|
||
border-radius: 2px;
|
||
resize: vertical;
|
||
}
|
||
.detail-share-dialog-text:focus {
|
||
outline: none;
|
||
border-color: var(--coral);
|
||
}
|
||
.detail-share-dialog-actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
.detail-share-dialog-actions .btn {
|
||
flex: 1 1 auto;
|
||
text-align: center;
|
||
}
|
||
.detail-share-dialog-copy[data-copied],
|
||
.detail-share-dialog-copy-link[data-copied] {
|
||
background: var(--coral) !important;
|
||
color: var(--paper) !important;
|
||
border-color: var(--coral) !important;
|
||
}
|
||
.detail-share-dialog-platforms {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
align-items: center;
|
||
padding-top: 8px;
|
||
border-top: 1px solid var(--line-soft);
|
||
}
|
||
.detail-share-dialog-platforms-label {
|
||
font-family: var(--mono);
|
||
font-size: 10.5px;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
margin-right: 4px;
|
||
}
|
||
.detail-share-platform-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 40px;
|
||
height: 40px;
|
||
border: 1px solid var(--ink);
|
||
border-radius: 50%;
|
||
color: var(--ink);
|
||
text-decoration: none;
|
||
background: transparent;
|
||
transition: background 0.12s ease, color 0.12s ease, transform 0.12s ease;
|
||
}
|
||
.detail-share-platform-btn:hover {
|
||
background: var(--ink);
|
||
color: var(--paper);
|
||
transform: translateY(-1px);
|
||
}
|
||
.detail-share-platform-btn svg {
|
||
display: block;
|
||
}
|
||
/* Visually-hidden helper for screen-reader-only platform names. */
|
||
.sr-only {
|
||
position: absolute;
|
||
width: 1px;
|
||
height: 1px;
|
||
padding: 0;
|
||
margin: -1px;
|
||
overflow: hidden;
|
||
clip: rect(0, 0, 0, 0);
|
||
white-space: nowrap;
|
||
border: 0;
|
||
}
|
||
|
||
/* The trigger button itself in `.detail-actions` */
|
||
.detail-share-trigger {
|
||
/* uses existing `.btn .btn-ghost` styling; this just lets future
|
||
* code target it for analytics or a11y customizations */
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.detail-preview-popout { top: 8px; right: 8px; padding: 4px 10px; font-size: 9.5px; }
|
||
.detail-share-dialog-form { padding: 20px 22px 24px; }
|
||
.detail-share-dialog-actions { flex-direction: column; }
|
||
}
|
||
|
||
/*
|
||
* Plugins hub — 4-tile grid for the /plugins/ landing surface. Used
|
||
* by `app/pages/plugins/index.astro` (default locale) and the
|
||
* `[locale]/[...path].astro` catch-all (prefixed locales) so the
|
||
* localized chrome reuses the same style without rendering twice.
|
||
*/
|
||
.plugins-tile-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 16px;
|
||
margin: 32px 0 64px;
|
||
}
|
||
@media (max-width: 720px) {
|
||
.plugins-tile-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
.plugins-tile {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 18px;
|
||
padding: 28px 28px 24px;
|
||
border: 1px solid var(--line);
|
||
background: var(--paper-warm);
|
||
color: var(--ink);
|
||
text-decoration: none;
|
||
transition: border-color 0.16s ease, transform 0.16s ease, background 0.16s ease;
|
||
}
|
||
.plugins-tile:hover {
|
||
border-color: var(--ink);
|
||
transform: translateY(-2px);
|
||
background: rgba(255, 255, 255, 0.4);
|
||
}
|
||
.plugins-tile-head {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: baseline;
|
||
gap: 16px;
|
||
}
|
||
.plugins-tile-title {
|
||
margin: 0;
|
||
font-family: var(--serif);
|
||
font-weight: 700;
|
||
font-size: 32px;
|
||
letter-spacing: -0.015em;
|
||
line-height: 1;
|
||
}
|
||
.plugins-tile-count {
|
||
font-family: var(--mono);
|
||
font-size: 14px;
|
||
color: var(--ink-mute);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.plugins-tile-blurb {
|
||
margin: 0;
|
||
font-size: 15px;
|
||
line-height: 1.55;
|
||
color: var(--ink-mute);
|
||
}
|
||
.plugins-tile-cta {
|
||
font-family: var(--mono);
|
||
font-size: 12px;
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
margin-top: auto;
|
||
padding-top: 8px;
|
||
border-top: 1px solid var(--line-soft);
|
||
}
|
||
|
||
/*
|
||
* ─── /plugins/templates/ grid (YouMind-inspired) ───────────────
|
||
* Card layout used by `template-card.astro`. Keeps `.catalog-grid`
|
||
* + `.catalog-row` available for /plugins/skills/ and other list
|
||
* surfaces, and ships alongside them so a single page can mix list
|
||
* + grid (the `index.astro` for templates uses grid; sub-routes can
|
||
* choose whichever shape fits).
|
||
*/
|
||
.tpl-counter {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 6px 16px;
|
||
background: var(--mustard);
|
||
color: var(--ink);
|
||
font-family: var(--mono);
|
||
font-size: 12px;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
border: 1.5px solid var(--ink);
|
||
box-shadow: 3px 3px 0 var(--ink);
|
||
white-space: nowrap;
|
||
}
|
||
.tpl-counter strong {
|
||
font-family: var(--sans);
|
||
font-weight: 800;
|
||
font-size: 18px;
|
||
letter-spacing: -0.005em;
|
||
text-transform: none;
|
||
}
|
||
|
||
.tpl-hero {
|
||
display: grid;
|
||
grid-template-columns: 1fr auto;
|
||
gap: 32px;
|
||
align-items: end;
|
||
margin: 12px 0 28px;
|
||
}
|
||
.tpl-hero-text { min-width: 0; }
|
||
.tpl-hero-side {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
}
|
||
@media (max-width: 720px) {
|
||
.tpl-hero { grid-template-columns: 1fr; align-items: start; }
|
||
.tpl-hero-side { justify-content: flex-start; }
|
||
}
|
||
|
||
.tpl-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
||
gap: 28px;
|
||
margin-top: 28px;
|
||
}
|
||
@media (max-width: 720px) {
|
||
.tpl-grid { grid-template-columns: 1fr; gap: 20px; }
|
||
}
|
||
|
||
.tpl-card {
|
||
position: relative;
|
||
display: grid;
|
||
grid-template-rows: auto auto auto 1fr auto;
|
||
gap: 12px;
|
||
background: var(--bone);
|
||
border: 1.5px solid var(--ink);
|
||
padding: 0 16px 16px;
|
||
overflow: hidden;
|
||
transition: transform 0.18s ease, box-shadow 0.18s ease;
|
||
}
|
||
.tpl-card:hover {
|
||
transform: translate(-2px, -2px);
|
||
box-shadow: 6px 6px 0 var(--ink);
|
||
}
|
||
.tpl-band {
|
||
display: block;
|
||
height: 6px;
|
||
margin: 0 -16px;
|
||
}
|
||
.tpl-featured-tag {
|
||
position: absolute;
|
||
top: -12px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
padding: 4px 14px;
|
||
background: var(--mustard);
|
||
border: 1.5px solid var(--ink);
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink);
|
||
z-index: 2;
|
||
}
|
||
|
||
.tpl-media {
|
||
position: relative;
|
||
display: block;
|
||
margin: 0 -16px;
|
||
aspect-ratio: 16 / 10;
|
||
background: var(--paper-warm);
|
||
overflow: hidden;
|
||
text-decoration: none;
|
||
border-bottom: 1.5px solid var(--ink);
|
||
}
|
||
.tpl-media-video,
|
||
.tpl-media-poster {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
display: block;
|
||
}
|
||
.tpl-media-empty {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
background:
|
||
repeating-linear-gradient(
|
||
135deg,
|
||
var(--paper-dark),
|
||
var(--paper-dark) 10px,
|
||
var(--paper-warm) 10px,
|
||
var(--paper-warm) 20px
|
||
);
|
||
}
|
||
.tpl-media-kind {
|
||
position: absolute;
|
||
right: 10px;
|
||
bottom: 10px;
|
||
padding: 4px 10px;
|
||
background: rgba(21, 20, 15, 0.72);
|
||
color: #f7f1de;
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
backdrop-filter: blur(6px);
|
||
}
|
||
|
||
.tpl-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
font-family: var(--mono);
|
||
font-size: 11px;
|
||
letter-spacing: 0.08em;
|
||
color: var(--ink-mute);
|
||
text-transform: uppercase;
|
||
}
|
||
.tpl-author {
|
||
color: var(--ink);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.tpl-excerpt {
|
||
display: block;
|
||
text-decoration: none;
|
||
color: var(--ink);
|
||
border: 1.5px solid var(--ink);
|
||
background: var(--paper);
|
||
padding: 12px 14px 14px;
|
||
transition: background 0.16s ease;
|
||
}
|
||
.tpl-excerpt:hover { background: var(--paper-warm); }
|
||
.tpl-excerpt-head {
|
||
display: block;
|
||
font-family: var(--mono);
|
||
font-size: 10px;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-mute);
|
||
padding-bottom: 8px;
|
||
margin-bottom: 8px;
|
||
border-bottom: 1px solid var(--line-soft);
|
||
}
|
||
.tpl-excerpt-title {
|
||
font-family: var(--sans);
|
||
font-weight: 600;
|
||
font-size: 16px;
|
||
line-height: 1.3;
|
||
letter-spacing: -0.005em;
|
||
color: var(--ink);
|
||
margin-bottom: 6px;
|
||
}
|
||
.tpl-excerpt-body {
|
||
font-size: 13px;
|
||
line-height: 1.55;
|
||
color: var(--ink-soft);
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 4;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.tpl-actions {
|
||
display: block;
|
||
}
|
||
.tpl-cta {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 44px;
|
||
background: var(--ink);
|
||
color: var(--bone);
|
||
font-family: var(--sans);
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
letter-spacing: 0.005em;
|
||
text-decoration: none;
|
||
border: 1.5px solid var(--ink);
|
||
transition: background 0.16s ease;
|
||
}
|
||
.tpl-cta:hover { background: var(--coral); border-color: var(--coral); }
|
||
.tpl-share {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 44px;
|
||
height: 44px;
|
||
background: var(--bone);
|
||
color: var(--ink);
|
||
border: 1.5px solid var(--ink);
|
||
cursor: pointer;
|
||
transition: background 0.16s ease;
|
||
}
|
||
.tpl-share:hover { background: var(--paper-warm); }
|
||
|
||
/*
|
||
* ─── FAQ section (YouMind-style accordion) ─────────────────────
|
||
*/
|
||
.tpl-faq {
|
||
margin: 96px 0 56px;
|
||
border-top: 1.5px solid var(--ink);
|
||
padding-top: 32px;
|
||
}
|
||
.tpl-faq-head {
|
||
font-family: var(--serif);
|
||
font-weight: 500;
|
||
font-size: 36px;
|
||
letter-spacing: -0.01em;
|
||
margin-bottom: 24px;
|
||
color: var(--ink);
|
||
}
|
||
.tpl-faq-list { display: grid; gap: 0; }
|
||
.tpl-faq-item {
|
||
border-bottom: 1px solid var(--line);
|
||
padding: 18px 0;
|
||
}
|
||
.tpl-faq-item summary {
|
||
list-style: none;
|
||
cursor: pointer;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 16px;
|
||
font-family: var(--sans);
|
||
font-weight: 600;
|
||
font-size: 17px;
|
||
color: var(--ink);
|
||
}
|
||
.tpl-faq-item summary::-webkit-details-marker { display: none; }
|
||
.tpl-faq-item summary::after {
|
||
content: '+';
|
||
font-family: var(--mono);
|
||
font-size: 22px;
|
||
color: var(--ink-mute);
|
||
transition: transform 0.18s ease;
|
||
}
|
||
.tpl-faq-item[open] summary::after { content: '−'; color: var(--coral); }
|
||
.tpl-faq-body {
|
||
margin-top: 12px;
|
||
font-size: 14.5px;
|
||
line-height: 1.7;
|
||
color: var(--ink-soft);
|
||
}
|
||
.tpl-faq-body p { margin-bottom: 8px; }
|
||
.tpl-faq-body p:last-child { margin-bottom: 0; }
|
||
.tpl-faq-body a { color: var(--coral); border-bottom: 1px solid currentColor; }
|
||
|
||
/*
|
||
* Card-level share toast (templates pages). Single instance per page,
|
||
* fades in for ~2.4s after the click handler copies the share text to
|
||
* the clipboard or the user's Web Share sheet closes. Bottom-center
|
||
* positioning so it doesn't collide with the fixed footer; pointer-
|
||
* events: none so the toast itself never swallows clicks.
|
||
*/
|
||
.tpl-share-toast {
|
||
position: fixed;
|
||
left: 50%;
|
||
bottom: 32px;
|
||
transform: translate(-50%, 12px);
|
||
padding: 12px 18px;
|
||
background: var(--ink);
|
||
color: var(--bone);
|
||
font-family: var(--sans);
|
||
font-size: 13.5px;
|
||
letter-spacing: 0.01em;
|
||
border: 1.5px solid var(--ink);
|
||
box-shadow: 0 12px 30px -12px rgba(21, 20, 15, 0.45);
|
||
pointer-events: none;
|
||
opacity: 0;
|
||
z-index: 50;
|
||
transition: opacity 0.18s cubic-bezier(0.23, 1, 0.32, 1),
|
||
transform 0.18s cubic-bezier(0.23, 1, 0.32, 1);
|
||
}
|
||
.tpl-share-toast.is-visible {
|
||
opacity: 1;
|
||
transform: translate(-50%, 0);
|
||
}
|
||
|
||
/*
|
||
* ─── Templates page share popover ───────────────────────────────
|
||
* Reuses the `.detail-share-dialog` skin from the detail page (same
|
||
* textarea + Copy buttons + 4-platform jump rail) but escapes the
|
||
* default `<dialog>` modal centering. The catalog's share button is
|
||
* anchored to a specific card; the popup needs to read as "this
|
||
* card" rather than as a page-level modal that could belong to
|
||
* anything. Inline `top` / `left` come from the JS positioner per
|
||
* click; the rules here just supply the geometry the positioner
|
||
* counts on (no `margin: auto`, fixed positioning, narrower max
|
||
* width, no backdrop, lighter shadow).
|
||
*/
|
||
dialog.tpl-share-popover {
|
||
position: fixed;
|
||
inset: auto;
|
||
margin: 0;
|
||
width: min(420px, calc(100vw - 32px));
|
||
box-shadow: 0 18px 48px -16px rgba(21, 20, 15, 0.32),
|
||
0 6px 14px -8px rgba(21, 20, 15, 0.18);
|
||
/* JS sets top + left based on the trigger's bounding rect. The
|
||
defaults are off-screen so a pre-position render doesn't flash
|
||
in the wrong place. */
|
||
top: -9999px;
|
||
left: -9999px;
|
||
}
|
||
dialog.tpl-share-popover::backdrop {
|
||
/* Non-modal — `.show()` skips the backdrop entirely. Hide it for
|
||
the rare older browser that treats every dialog as modal. */
|
||
background: transparent;
|
||
}
|
||
dialog.tpl-share-popover .detail-share-dialog-form {
|
||
padding: 18px 20px 20px;
|
||
gap: 12px;
|
||
}
|
||
dialog.tpl-share-popover .detail-share-dialog-head h2 {
|
||
font-size: 18px;
|
||
}
|
||
dialog.tpl-share-popover .detail-share-dialog-lead {
|
||
font-size: 12.5px;
|
||
}
|
||
dialog.tpl-share-popover .detail-share-dialog-text {
|
||
rows: 5;
|
||
font-size: 12.5px;
|
||
line-height: 1.55;
|
||
}
|