197 lines
4.5 KiB
Plaintext
197 lines
4.5 KiB
Plaintext
---
|
||
// One bento tile in the capabilities grid - size/flavour driven by the data
|
||
// (span: hero 2×2 flagship · wide 2×1 · full row · default 1×1).
|
||
import type { SkillGroup } from "../data/skills";
|
||
|
||
interface Props {
|
||
group: SkillGroup;
|
||
}
|
||
const { group } = Astro.props;
|
||
const spanClass =
|
||
group.span === "hero"
|
||
? "tile--hero"
|
||
: group.span === "wide"
|
||
? "tile--wide"
|
||
: group.span === "full"
|
||
? "tile--full"
|
||
: "";
|
||
---
|
||
|
||
<article
|
||
class:list={["tile", spanClass, group.flavor === "magenta" && "tile--magenta"]}
|
||
data-reveal
|
||
>
|
||
{group.span === "hero" && <div class="tile__corner" aria-hidden="true" />}
|
||
{group.flag && <p class="tile__flag mono">{group.flag}</p>}
|
||
<h3 class="tile__title">{group.title}</h3>
|
||
<p class="tile__blurb">{group.blurb}</p>
|
||
{group.points && (
|
||
<ul class="tile__points" role="list">
|
||
{group.points.map((point) => (
|
||
<li>{point}</li>
|
||
))}
|
||
</ul>
|
||
)}
|
||
<ul class="tile__chips mono" role="list">
|
||
{group.items.map((item) => (
|
||
<li class:list={["chip", group.span === "hero" && "chip--lit"]}>{item}</li>
|
||
))}
|
||
</ul>
|
||
</article>
|
||
|
||
<style>
|
||
.tile {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
padding: 28px;
|
||
background: var(--panel);
|
||
border: 1px solid var(--border-accent);
|
||
border-radius: 10px;
|
||
backdrop-filter: var(--panel-blur);
|
||
-webkit-backdrop-filter: var(--panel-blur);
|
||
transition:
|
||
border-color 180ms var(--ease),
|
||
box-shadow 180ms var(--ease);
|
||
}
|
||
.tile:hover {
|
||
border-color: var(--border-accent-hover);
|
||
box-shadow: var(--glow-card);
|
||
}
|
||
.tile--magenta {
|
||
border-color: var(--border-magenta);
|
||
}
|
||
.tile--magenta:hover {
|
||
border-color: rgba(232, 121, 249, 0.5);
|
||
box-shadow: var(--glow-card-magenta);
|
||
}
|
||
|
||
.tile--hero {
|
||
grid-column: span 2;
|
||
grid-row: span 2;
|
||
padding: 32px;
|
||
gap: 16px;
|
||
border-color: rgba(63, 186, 245, 0.2);
|
||
}
|
||
.tile--wide {
|
||
grid-column: span 2;
|
||
}
|
||
.tile--full {
|
||
/* "full" = the row-completer: 3 columns, sharing its row with the 1×1 before it */
|
||
grid-column: span 3;
|
||
}
|
||
|
||
.tile__corner {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: radial-gradient(
|
||
500px 320px at 85% 100%,
|
||
rgba(232, 121, 249, 0.1),
|
||
transparent 70%
|
||
);
|
||
pointer-events: none;
|
||
}
|
||
.tile__flag {
|
||
position: relative;
|
||
margin: 0;
|
||
font-size: 11px;
|
||
letter-spacing: 0.14em;
|
||
color: var(--accent-2);
|
||
}
|
||
.tile__title {
|
||
position: relative;
|
||
margin: 0;
|
||
font-family: var(--font-display);
|
||
font-size: 23px;
|
||
font-weight: 700;
|
||
color: var(--text-strong);
|
||
}
|
||
.tile--hero .tile__title {
|
||
font-size: 30px;
|
||
}
|
||
.tile__blurb {
|
||
position: relative;
|
||
margin: 0;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
color: var(--text-secondary);
|
||
text-wrap: pretty;
|
||
}
|
||
.tile--hero .tile__blurb {
|
||
font-size: 15px;
|
||
color: var(--text-dim);
|
||
max-width: 420px;
|
||
}
|
||
|
||
.tile__points {
|
||
position: relative;
|
||
list-style: none;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
margin: 6px 0 0;
|
||
padding: 0;
|
||
font-size: 13.5px;
|
||
line-height: 1.55;
|
||
color: var(--text-dim);
|
||
}
|
||
.tile__points li {
|
||
padding-left: 18px;
|
||
position: relative;
|
||
text-wrap: pretty;
|
||
}
|
||
.tile__points li::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0.55em;
|
||
width: 8px;
|
||
height: 2px;
|
||
background: linear-gradient(90deg, var(--accent), var(--accent-2));
|
||
border-radius: 1px;
|
||
}
|
||
.tile--hero .tile__points {
|
||
font-size: 14.5px;
|
||
gap: 12px;
|
||
max-width: 460px;
|
||
}
|
||
|
||
.tile__chips {
|
||
position: relative;
|
||
list-style: none;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 7px;
|
||
margin: auto 0 0;
|
||
padding: 0;
|
||
font-size: 11.5px;
|
||
color: var(--text-dim);
|
||
}
|
||
.chip {
|
||
border: 1px solid rgba(126, 139, 161, 0.25);
|
||
border-radius: var(--radius-chip);
|
||
padding: 4px 9px;
|
||
}
|
||
.chip--lit {
|
||
font-size: 12px;
|
||
color: var(--text-body-strong);
|
||
border-color: rgba(63, 186, 245, 0.3);
|
||
padding: 5px 10px;
|
||
}
|
||
|
||
/* Below 1000px the parent grid is only 2 columns - so the multi-column spans
|
||
must collapse to full-width HERE, not at 720px. A `span 3` tile left active
|
||
in a 2-col grid forces a phantom 3rd column and collapses the 1fr tracks
|
||
(58px 58px 760px), squishing the first tile to ~130px in landscape phone. */
|
||
@media (max-width: 1000px) {
|
||
.tile--hero,
|
||
.tile--wide,
|
||
.tile--full {
|
||
grid-column: 1 / -1;
|
||
grid-row: auto;
|
||
}
|
||
}
|
||
</style>
|