Refactoring CSS cards parcours : CSS partagé, propriétés logiques, suppression des !important et de la duplication 3x
This commit is contained in:
parent
8728594347
commit
5b887c7926
5 changed files with 177 additions and 253 deletions
|
|
@ -55,25 +55,33 @@ const locale = pathname.startsWith("/en")
|
||||||
color: rgba(255, 255, 255, 0.85) !important;
|
color: rgba(255, 255, 255, 0.85) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Page-level text overrides for the purple gradient.
|
||||||
|
* Any component that manages its own colors should add
|
||||||
|
* the `.code-card` class — it will be excluded automatically.
|
||||||
|
*/
|
||||||
[data-facet="code"] > section h1,
|
[data-facet="code"] > section h1,
|
||||||
[data-facet="code"] > section h2,
|
[data-facet="code"] > section h2 {
|
||||||
[data-facet="code"] > section h3:not(.exp-card h3):not(.facet-card h3),
|
|
||||||
[data-facet="code"] > section strong:not(.exp-card strong):not(.facet-card strong) {
|
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-facet="code"] > section a:not(.facet-card a) {
|
[data-facet="code"] > section h3:not(.code-card h3),
|
||||||
|
[data-facet="code"] > section strong:not(.code-card strong) {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-facet="code"] > section a:not(.code-card a) {
|
||||||
color: #d4b5ff !important;
|
color: #d4b5ff !important;
|
||||||
text-decoration-color: rgba(212, 181, 255, 0.3) !important;
|
text-decoration-color: rgba(212, 181, 255, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-facet="code"] > section a:not(.facet-card a):hover {
|
[data-facet="code"] > section a:not(.code-card a):hover {
|
||||||
color: white !important;
|
color: white !important;
|
||||||
text-decoration-color: white !important;
|
text-decoration-color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-facet="code"] > section p:not(.exp-card p):not(.facet-card p),
|
[data-facet="code"] > section p:not(.code-card p),
|
||||||
[data-facet="code"] > section li:not(.exp-card li):not(.facet-card li) {
|
[data-facet="code"] > section li:not(.code-card li) {
|
||||||
color: rgba(255, 255, 255, 0.75) !important;
|
color: rgba(255, 255, 255, 0.75) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { getCollection, render } from "astro:content";
|
import { getCollection, render } from "astro:content";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import Layout from "../../../layouts/main.astro";
|
import Layout from "../../../layouts/main.astro";
|
||||||
|
import "../../../styles/exp-card.css";
|
||||||
|
|
||||||
const logos = import.meta.glob<{ default: ImageMetadata }>('../../../assets/images/companies/*.png', { eager: true });
|
const logos = import.meta.glob<{ default: ImageMetadata }>('../../../assets/images/companies/*.png', { eager: true });
|
||||||
|
|
||||||
|
|
@ -91,12 +92,12 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class:list={[
|
<div class:list={[
|
||||||
"exp-card relative rounded-2xl p-6 transition-colors duration-200 border-r-[3px]",
|
"code-card exp-card relative rounded-2xl p-6 transition-colors duration-200 border-s-[3px]",
|
||||||
isOngoing ? "exp-card--ongoing" : "",
|
isOngoing ? "exp-card--ongoing" : "",
|
||||||
colors.border
|
colors.border
|
||||||
]}>
|
]}>
|
||||||
{getLogo(exp.data.logo) ? (
|
{getLogo(exp.data.logo) ? (
|
||||||
<div class="exp-logo absolute top-5 left-5 w-16 h-16 rounded-xl flex items-center justify-center p-2">
|
<div class="exp-logo absolute top-5 end-5 w-16 h-16 rounded-xl flex items-center justify-center p-2">
|
||||||
<Image
|
<Image
|
||||||
src={getLogo(exp.data.logo)!}
|
src={getLogo(exp.data.logo)!}
|
||||||
alt={`شعار ${exp.data.company}`}
|
alt={`شعار ${exp.data.company}`}
|
||||||
|
|
@ -106,12 +107,12 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div class="exp-logo-fallback absolute top-5 left-5 w-16 h-16 rounded-xl flex items-center justify-center">
|
<div class="exp-logo-fallback absolute top-5 end-5 w-16 h-16 rounded-xl flex items-center justify-center">
|
||||||
<span class="text-base font-bold">{getInitials(exp.data.company)}</span>
|
<span class="text-base font-bold">{getInitials(exp.data.company)}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="mb-3 flex items-center gap-2 flex-wrap pl-20">
|
<div class="mb-3 flex items-center gap-2 flex-wrap pe-20">
|
||||||
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
|
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -122,7 +123,7 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>}
|
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="text-xl font-bold pl-20">{exp.data.role}</h3>
|
<h3 class="text-xl font-bold pe-20">{exp.data.role}</h3>
|
||||||
<p class="exp-company text-sm font-medium mt-1 mb-3">
|
<p class="exp-company text-sm font-medium mt-1 mb-3">
|
||||||
{exp.data.companyUrl ? (
|
{exp.data.companyUrl ? (
|
||||||
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="transition-colors">{exp.data.company}</a>
|
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="transition-colors">{exp.data.company}</a>
|
||||||
|
|
@ -149,80 +150,3 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
|
||||||
/* ── Light mode (default): white cards on purple gradient ── */
|
|
||||||
.exp-card {
|
|
||||||
background: white;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
.exp-card--ongoing { box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.25), 0 1px 3px rgba(0, 0, 0, 0.08); }
|
|
||||||
.exp-card h3 { color: #111827 !important; }
|
|
||||||
.exp-card .exp-meta { color: #9ca3af; }
|
|
||||||
.exp-card .exp-company { color: #6b21a8; }
|
|
||||||
.exp-card .exp-company a { color: #6b21a8 !important; text-decoration: none !important; }
|
|
||||||
.exp-card .exp-company a:hover { color: #581c87 !important; }
|
|
||||||
.exp-card .exp-content,
|
|
||||||
.exp-card .exp-content p { color: #4b5563 !important; }
|
|
||||||
.exp-card .exp-content a { color: #6b21a8 !important; text-decoration-color: rgba(107, 33, 168, 0.3) !important; }
|
|
||||||
.exp-card .exp-content a:hover { color: #581c87 !important; }
|
|
||||||
.exp-card .exp-tech { background: #f3f4f6; color: #6b7280; border-color: #e5e7eb; }
|
|
||||||
.exp-logo { background: #f9fafb; border: 1px solid #e5e7eb; }
|
|
||||||
.exp-logo-fallback { background: #f3f4f6; border: 1px solid #e5e7eb; }
|
|
||||||
.exp-logo-fallback span { color: #9ca3af; }
|
|
||||||
|
|
||||||
/* Type badges – light */
|
|
||||||
.type-badge-blue { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
|
|
||||||
.type-badge-amber { background: #fffbeb; color: #b45309; border-color: #fde68a; }
|
|
||||||
.type-badge-emerald { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
|
|
||||||
.type-badge-pink { background: #fdf2f8; color: #be185d; border-color: #fbcfe8; }
|
|
||||||
.type-badge-purple { background: #faf5ff; color: #7e22ce; border-color: #e9d5ff; }
|
|
||||||
|
|
||||||
/* Type borders – light (RTL: border-right) */
|
|
||||||
.type-border-blue { border-right-color: #3b82f6 !important; }
|
|
||||||
.type-border-amber { border-right-color: #f59e0b !important; }
|
|
||||||
.type-border-emerald { border-right-color: #10b981 !important; }
|
|
||||||
.type-border-pink { border-right-color: #ec4899 !important; }
|
|
||||||
.type-border-purple { border-right-color: #a855f7 !important; }
|
|
||||||
|
|
||||||
/* ── Dark mode: translucent cards ── */
|
|
||||||
:global(.dark) .exp-card {
|
|
||||||
background: rgba(255, 255, 255, 0.03);
|
|
||||||
border-color: rgba(255, 255, 255, 0.08);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
:global(.dark) .exp-card:hover { background: rgba(255, 255, 255, 0.06); }
|
|
||||||
:global(.dark) .exp-card--ongoing {
|
|
||||||
background: rgba(255, 255, 255, 0.07);
|
|
||||||
border-color: rgba(255, 255, 255, 0.12);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
:global(.dark) .exp-card h3 { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-meta { color: rgba(255, 255, 255, 0.3); }
|
|
||||||
:global(.dark) .exp-card .exp-company { color: #d4b5ff; }
|
|
||||||
:global(.dark) .exp-card .exp-company a { color: #d4b5ff !important; }
|
|
||||||
:global(.dark) .exp-card .exp-company a:hover { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content,
|
|
||||||
:global(.dark) .exp-card .exp-content p { color: rgba(255, 255, 255, 0.6) !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content a { color: #d4b5ff !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content a:hover { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-tech { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.45); border-color: rgba(255, 255, 255, 0.06); }
|
|
||||||
:global(.dark) .exp-logo { background: white; border-color: rgba(255, 255, 255, 0.2); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); }
|
|
||||||
:global(.dark) .exp-logo-fallback { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.1); }
|
|
||||||
:global(.dark) .exp-logo-fallback span { color: rgba(255, 255, 255, 0.4); }
|
|
||||||
|
|
||||||
/* Type badges – dark */
|
|
||||||
:global(.dark) .type-badge-blue { background: rgba(96, 165, 250, 0.15); color: #93c5fd; border-color: rgba(96, 165, 250, 0.2); }
|
|
||||||
:global(.dark) .type-badge-amber { background: rgba(251, 191, 36, 0.15); color: #fcd34d; border-color: rgba(251, 191, 36, 0.2); }
|
|
||||||
:global(.dark) .type-badge-emerald { background: rgba(52, 211, 153, 0.15); color: #6ee7b7; border-color: rgba(52, 211, 153, 0.2); }
|
|
||||||
:global(.dark) .type-badge-pink { background: rgba(244, 114, 182, 0.15); color: #f9a8d4; border-color: rgba(244, 114, 182, 0.2); }
|
|
||||||
:global(.dark) .type-badge-purple { background: rgba(168, 85, 247, 0.15); color: #d4b5ff; border-color: rgba(168, 85, 247, 0.2); }
|
|
||||||
|
|
||||||
/* Type borders – dark (RTL: border-right) */
|
|
||||||
:global(.dark) .type-border-blue { border-right-color: rgba(96, 165, 250, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-amber { border-right-color: rgba(251, 191, 36, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-emerald { border-right-color: rgba(52, 211, 153, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-pink { border-right-color: rgba(244, 114, 182, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-purple { border-right-color: rgba(168, 85, 247, 0.4) !important; }
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { getCollection, render } from "astro:content";
|
import { getCollection, render } from "astro:content";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import Layout from "../../layouts/main.astro";
|
import Layout from "../../layouts/main.astro";
|
||||||
|
import "../../styles/exp-card.css";
|
||||||
|
|
||||||
const logos = import.meta.glob<{ default: ImageMetadata }>('../../assets/images/companies/*.png', { eager: true });
|
const logos = import.meta.glob<{ default: ImageMetadata }>('../../assets/images/companies/*.png', { eager: true });
|
||||||
|
|
||||||
|
|
@ -91,12 +92,12 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class:list={[
|
<div class:list={[
|
||||||
"exp-card relative rounded-2xl p-6 transition-colors duration-200 border-l-[3px]",
|
"code-card exp-card relative rounded-2xl p-6 transition-colors duration-200 border-s-[3px]",
|
||||||
isOngoing ? "exp-card--ongoing" : "",
|
isOngoing ? "exp-card--ongoing" : "",
|
||||||
colors.border
|
colors.border
|
||||||
]}>
|
]}>
|
||||||
{getLogo(exp.data.logo) ? (
|
{getLogo(exp.data.logo) ? (
|
||||||
<div class="exp-logo absolute top-5 right-5 w-16 h-16 rounded-xl flex items-center justify-center p-2">
|
<div class="exp-logo absolute top-5 end-5 w-16 h-16 rounded-xl flex items-center justify-center p-2">
|
||||||
<Image
|
<Image
|
||||||
src={getLogo(exp.data.logo)!}
|
src={getLogo(exp.data.logo)!}
|
||||||
alt={`Logo ${exp.data.company}`}
|
alt={`Logo ${exp.data.company}`}
|
||||||
|
|
@ -106,12 +107,12 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div class="exp-logo-fallback absolute top-5 right-5 w-16 h-16 rounded-xl flex items-center justify-center">
|
<div class="exp-logo-fallback absolute top-5 end-5 w-16 h-16 rounded-xl flex items-center justify-center">
|
||||||
<span class="text-base font-bold">{getInitials(exp.data.company)}</span>
|
<span class="text-base font-bold">{getInitials(exp.data.company)}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="mb-3 flex items-center gap-2 flex-wrap pr-20">
|
<div class="mb-3 flex items-center gap-2 flex-wrap pe-20">
|
||||||
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
|
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -122,7 +123,7 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>}
|
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="text-xl font-bold pr-20">{exp.data.role}</h3>
|
<h3 class="text-xl font-bold pe-20">{exp.data.role}</h3>
|
||||||
<p class="exp-company text-sm font-medium mt-1 mb-3">
|
<p class="exp-company text-sm font-medium mt-1 mb-3">
|
||||||
{exp.data.companyUrl ? (
|
{exp.data.companyUrl ? (
|
||||||
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="transition-colors">{exp.data.company}</a>
|
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="transition-colors">{exp.data.company}</a>
|
||||||
|
|
@ -149,80 +150,3 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
|
||||||
/* ── Light mode (default): white cards on purple gradient ── */
|
|
||||||
.exp-card {
|
|
||||||
background: white;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
.exp-card--ongoing { box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.25), 0 1px 3px rgba(0, 0, 0, 0.08); }
|
|
||||||
.exp-card h3 { color: #111827 !important; }
|
|
||||||
.exp-card .exp-meta { color: #9ca3af; }
|
|
||||||
.exp-card .exp-company { color: #6b21a8; }
|
|
||||||
.exp-card .exp-company a { color: #6b21a8 !important; text-decoration: none !important; }
|
|
||||||
.exp-card .exp-company a:hover { color: #581c87 !important; }
|
|
||||||
.exp-card .exp-content,
|
|
||||||
.exp-card .exp-content p { color: #4b5563 !important; }
|
|
||||||
.exp-card .exp-content a { color: #6b21a8 !important; text-decoration-color: rgba(107, 33, 168, 0.3) !important; }
|
|
||||||
.exp-card .exp-content a:hover { color: #581c87 !important; }
|
|
||||||
.exp-card .exp-tech { background: #f3f4f6; color: #6b7280; border-color: #e5e7eb; }
|
|
||||||
.exp-logo { background: #f9fafb; border: 1px solid #e5e7eb; }
|
|
||||||
.exp-logo-fallback { background: #f3f4f6; border: 1px solid #e5e7eb; }
|
|
||||||
.exp-logo-fallback span { color: #9ca3af; }
|
|
||||||
|
|
||||||
/* Type badges – light */
|
|
||||||
.type-badge-blue { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
|
|
||||||
.type-badge-amber { background: #fffbeb; color: #b45309; border-color: #fde68a; }
|
|
||||||
.type-badge-emerald { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
|
|
||||||
.type-badge-pink { background: #fdf2f8; color: #be185d; border-color: #fbcfe8; }
|
|
||||||
.type-badge-purple { background: #faf5ff; color: #7e22ce; border-color: #e9d5ff; }
|
|
||||||
|
|
||||||
/* Type borders – light */
|
|
||||||
.type-border-blue { border-left-color: #3b82f6 !important; }
|
|
||||||
.type-border-amber { border-left-color: #f59e0b !important; }
|
|
||||||
.type-border-emerald { border-left-color: #10b981 !important; }
|
|
||||||
.type-border-pink { border-left-color: #ec4899 !important; }
|
|
||||||
.type-border-purple { border-left-color: #a855f7 !important; }
|
|
||||||
|
|
||||||
/* ── Dark mode: translucent cards ── */
|
|
||||||
:global(.dark) .exp-card {
|
|
||||||
background: rgba(255, 255, 255, 0.03);
|
|
||||||
border-color: rgba(255, 255, 255, 0.08);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
:global(.dark) .exp-card:hover { background: rgba(255, 255, 255, 0.06); }
|
|
||||||
:global(.dark) .exp-card--ongoing {
|
|
||||||
background: rgba(255, 255, 255, 0.07);
|
|
||||||
border-color: rgba(255, 255, 255, 0.12);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
:global(.dark) .exp-card h3 { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-meta { color: rgba(255, 255, 255, 0.3); }
|
|
||||||
:global(.dark) .exp-card .exp-company { color: #d4b5ff; }
|
|
||||||
:global(.dark) .exp-card .exp-company a { color: #d4b5ff !important; }
|
|
||||||
:global(.dark) .exp-card .exp-company a:hover { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content,
|
|
||||||
:global(.dark) .exp-card .exp-content p { color: rgba(255, 255, 255, 0.6) !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content a { color: #d4b5ff !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content a:hover { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-tech { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.45); border-color: rgba(255, 255, 255, 0.06); }
|
|
||||||
:global(.dark) .exp-logo { background: white; border-color: rgba(255, 255, 255, 0.2); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); }
|
|
||||||
:global(.dark) .exp-logo-fallback { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.1); }
|
|
||||||
:global(.dark) .exp-logo-fallback span { color: rgba(255, 255, 255, 0.4); }
|
|
||||||
|
|
||||||
/* Type badges – dark */
|
|
||||||
:global(.dark) .type-badge-blue { background: rgba(96, 165, 250, 0.15); color: #93c5fd; border-color: rgba(96, 165, 250, 0.2); }
|
|
||||||
:global(.dark) .type-badge-amber { background: rgba(251, 191, 36, 0.15); color: #fcd34d; border-color: rgba(251, 191, 36, 0.2); }
|
|
||||||
:global(.dark) .type-badge-emerald { background: rgba(52, 211, 153, 0.15); color: #6ee7b7; border-color: rgba(52, 211, 153, 0.2); }
|
|
||||||
:global(.dark) .type-badge-pink { background: rgba(244, 114, 182, 0.15); color: #f9a8d4; border-color: rgba(244, 114, 182, 0.2); }
|
|
||||||
:global(.dark) .type-badge-purple { background: rgba(168, 85, 247, 0.15); color: #d4b5ff; border-color: rgba(168, 85, 247, 0.2); }
|
|
||||||
|
|
||||||
/* Type borders – dark */
|
|
||||||
:global(.dark) .type-border-blue { border-left-color: rgba(96, 165, 250, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-amber { border-left-color: rgba(251, 191, 36, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-emerald { border-left-color: rgba(52, 211, 153, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-pink { border-left-color: rgba(244, 114, 182, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-purple { border-left-color: rgba(168, 85, 247, 0.4) !important; }
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { getCollection, render } from "astro:content";
|
import { getCollection, render } from "astro:content";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import Layout from "../../../layouts/main.astro";
|
import Layout from "../../../layouts/main.astro";
|
||||||
|
import "../../../styles/exp-card.css";
|
||||||
|
|
||||||
const logos = import.meta.glob<{ default: ImageMetadata }>('../../../assets/images/companies/*.png', { eager: true });
|
const logos = import.meta.glob<{ default: ImageMetadata }>('../../../assets/images/companies/*.png', { eager: true });
|
||||||
|
|
||||||
|
|
@ -91,12 +92,12 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class:list={[
|
<div class:list={[
|
||||||
"exp-card relative rounded-2xl p-6 transition-colors duration-200 border-l-[3px]",
|
"code-card exp-card relative rounded-2xl p-6 transition-colors duration-200 border-s-[3px]",
|
||||||
isOngoing ? "exp-card--ongoing" : "",
|
isOngoing ? "exp-card--ongoing" : "",
|
||||||
colors.border
|
colors.border
|
||||||
]}>
|
]}>
|
||||||
{getLogo(exp.data.logo) ? (
|
{getLogo(exp.data.logo) ? (
|
||||||
<div class="exp-logo absolute top-5 right-5 w-16 h-16 rounded-xl flex items-center justify-center p-2">
|
<div class="exp-logo absolute top-5 end-5 w-16 h-16 rounded-xl flex items-center justify-center p-2">
|
||||||
<Image
|
<Image
|
||||||
src={getLogo(exp.data.logo)!}
|
src={getLogo(exp.data.logo)!}
|
||||||
alt={`${exp.data.company} logo`}
|
alt={`${exp.data.company} logo`}
|
||||||
|
|
@ -106,12 +107,12 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div class="exp-logo-fallback absolute top-5 right-5 w-16 h-16 rounded-xl flex items-center justify-center">
|
<div class="exp-logo-fallback absolute top-5 end-5 w-16 h-16 rounded-xl flex items-center justify-center">
|
||||||
<span class="text-base font-bold">{getInitials(exp.data.company)}</span>
|
<span class="text-base font-bold">{getInitials(exp.data.company)}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="mb-3 flex items-center gap-2 flex-wrap pr-20">
|
<div class="mb-3 flex items-center gap-2 flex-wrap pe-20">
|
||||||
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
|
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -122,7 +123,7 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>}
|
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="text-xl font-bold pr-20">{exp.data.role}</h3>
|
<h3 class="text-xl font-bold pe-20">{exp.data.role}</h3>
|
||||||
<p class="exp-company text-sm font-medium mt-1 mb-3">
|
<p class="exp-company text-sm font-medium mt-1 mb-3">
|
||||||
{exp.data.companyUrl ? (
|
{exp.data.companyUrl ? (
|
||||||
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="transition-colors">{exp.data.company}</a>
|
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="transition-colors">{exp.data.company}</a>
|
||||||
|
|
@ -149,80 +150,3 @@ function computeDuration(startStr: string, endStr?: string) {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
|
||||||
/* ── Light mode (default): white cards on purple gradient ── */
|
|
||||||
.exp-card {
|
|
||||||
background: white;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
.exp-card--ongoing { box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.25), 0 1px 3px rgba(0, 0, 0, 0.08); }
|
|
||||||
.exp-card h3 { color: #111827 !important; }
|
|
||||||
.exp-card .exp-meta { color: #9ca3af; }
|
|
||||||
.exp-card .exp-company { color: #6b21a8; }
|
|
||||||
.exp-card .exp-company a { color: #6b21a8 !important; text-decoration: none !important; }
|
|
||||||
.exp-card .exp-company a:hover { color: #581c87 !important; }
|
|
||||||
.exp-card .exp-content,
|
|
||||||
.exp-card .exp-content p { color: #4b5563 !important; }
|
|
||||||
.exp-card .exp-content a { color: #6b21a8 !important; text-decoration-color: rgba(107, 33, 168, 0.3) !important; }
|
|
||||||
.exp-card .exp-content a:hover { color: #581c87 !important; }
|
|
||||||
.exp-card .exp-tech { background: #f3f4f6; color: #6b7280; border-color: #e5e7eb; }
|
|
||||||
.exp-logo { background: #f9fafb; border: 1px solid #e5e7eb; }
|
|
||||||
.exp-logo-fallback { background: #f3f4f6; border: 1px solid #e5e7eb; }
|
|
||||||
.exp-logo-fallback span { color: #9ca3af; }
|
|
||||||
|
|
||||||
/* Type badges – light */
|
|
||||||
.type-badge-blue { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
|
|
||||||
.type-badge-amber { background: #fffbeb; color: #b45309; border-color: #fde68a; }
|
|
||||||
.type-badge-emerald { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
|
|
||||||
.type-badge-pink { background: #fdf2f8; color: #be185d; border-color: #fbcfe8; }
|
|
||||||
.type-badge-purple { background: #faf5ff; color: #7e22ce; border-color: #e9d5ff; }
|
|
||||||
|
|
||||||
/* Type borders – light */
|
|
||||||
.type-border-blue { border-left-color: #3b82f6 !important; }
|
|
||||||
.type-border-amber { border-left-color: #f59e0b !important; }
|
|
||||||
.type-border-emerald { border-left-color: #10b981 !important; }
|
|
||||||
.type-border-pink { border-left-color: #ec4899 !important; }
|
|
||||||
.type-border-purple { border-left-color: #a855f7 !important; }
|
|
||||||
|
|
||||||
/* ── Dark mode: translucent cards ── */
|
|
||||||
:global(.dark) .exp-card {
|
|
||||||
background: rgba(255, 255, 255, 0.03);
|
|
||||||
border-color: rgba(255, 255, 255, 0.08);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
:global(.dark) .exp-card:hover { background: rgba(255, 255, 255, 0.06); }
|
|
||||||
:global(.dark) .exp-card--ongoing {
|
|
||||||
background: rgba(255, 255, 255, 0.07);
|
|
||||||
border-color: rgba(255, 255, 255, 0.12);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
:global(.dark) .exp-card h3 { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-meta { color: rgba(255, 255, 255, 0.3); }
|
|
||||||
:global(.dark) .exp-card .exp-company { color: #d4b5ff; }
|
|
||||||
:global(.dark) .exp-card .exp-company a { color: #d4b5ff !important; }
|
|
||||||
:global(.dark) .exp-card .exp-company a:hover { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content,
|
|
||||||
:global(.dark) .exp-card .exp-content p { color: rgba(255, 255, 255, 0.6) !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content a { color: #d4b5ff !important; }
|
|
||||||
:global(.dark) .exp-card .exp-content a:hover { color: white !important; }
|
|
||||||
:global(.dark) .exp-card .exp-tech { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.45); border-color: rgba(255, 255, 255, 0.06); }
|
|
||||||
:global(.dark) .exp-logo { background: white; border-color: rgba(255, 255, 255, 0.2); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); }
|
|
||||||
:global(.dark) .exp-logo-fallback { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.1); }
|
|
||||||
:global(.dark) .exp-logo-fallback span { color: rgba(255, 255, 255, 0.4); }
|
|
||||||
|
|
||||||
/* Type badges – dark */
|
|
||||||
:global(.dark) .type-badge-blue { background: rgba(96, 165, 250, 0.15); color: #93c5fd; border-color: rgba(96, 165, 250, 0.2); }
|
|
||||||
:global(.dark) .type-badge-amber { background: rgba(251, 191, 36, 0.15); color: #fcd34d; border-color: rgba(251, 191, 36, 0.2); }
|
|
||||||
:global(.dark) .type-badge-emerald { background: rgba(52, 211, 153, 0.15); color: #6ee7b7; border-color: rgba(52, 211, 153, 0.2); }
|
|
||||||
:global(.dark) .type-badge-pink { background: rgba(244, 114, 182, 0.15); color: #f9a8d4; border-color: rgba(244, 114, 182, 0.2); }
|
|
||||||
:global(.dark) .type-badge-purple { background: rgba(168, 85, 247, 0.15); color: #d4b5ff; border-color: rgba(168, 85, 247, 0.2); }
|
|
||||||
|
|
||||||
/* Type borders – dark */
|
|
||||||
:global(.dark) .type-border-blue { border-left-color: rgba(96, 165, 250, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-amber { border-left-color: rgba(251, 191, 36, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-emerald { border-left-color: rgba(52, 211, 153, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-pink { border-left-color: rgba(244, 114, 182, 0.4) !important; }
|
|
||||||
:global(.dark) .type-border-purple { border-left-color: rgba(168, 85, 247, 0.4) !important; }
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
144
src/styles/exp-card.css
Normal file
144
src/styles/exp-card.css
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Experience card styles — shared by FR, EN, AR career pages.
|
||||||
|
* Cards use the `.code-card` class to opt out of the layout's
|
||||||
|
* white-on-purple overrides (see main.astro).
|
||||||
|
*
|
||||||
|
* Light mode: white cards on purple gradient background.
|
||||||
|
* Dark mode: translucent cards blending into the gradient.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ────────────────────────────────────────────
|
||||||
|
Card container
|
||||||
|
──────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.exp-card {
|
||||||
|
background: white;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-card--ongoing {
|
||||||
|
box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.25),
|
||||||
|
0 1px 3px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-card {
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
border-color: rgba(255, 255, 255, 0.08);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-card:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-card--ongoing {
|
||||||
|
background: rgba(255, 255, 255, 0.07);
|
||||||
|
border-color: rgba(255, 255, 255, 0.12);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ────────────────────────────────────────────
|
||||||
|
Typography
|
||||||
|
──────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.exp-card h3 { color: #111827; }
|
||||||
|
.exp-card .exp-meta { color: #9ca3af; }
|
||||||
|
.exp-card .exp-company { color: #6b21a8; }
|
||||||
|
.exp-card .exp-company a { color: #6b21a8; text-decoration: none; }
|
||||||
|
.exp-card .exp-company a:hover { color: #581c87; }
|
||||||
|
.exp-card .exp-content,
|
||||||
|
.exp-card .exp-content p { color: #4b5563; }
|
||||||
|
.exp-card .exp-content a { color: #6b21a8; text-decoration-color: rgba(107, 33, 168, 0.3); }
|
||||||
|
.exp-card .exp-content a:hover { color: #581c87; }
|
||||||
|
|
||||||
|
.dark .exp-card h3 { color: white; }
|
||||||
|
.dark .exp-card .exp-meta { color: rgba(255, 255, 255, 0.3); }
|
||||||
|
.dark .exp-card .exp-company { color: #d4b5ff; }
|
||||||
|
.dark .exp-card .exp-company a { color: #d4b5ff; }
|
||||||
|
.dark .exp-card .exp-company a:hover { color: white; }
|
||||||
|
.dark .exp-card .exp-content,
|
||||||
|
.dark .exp-card .exp-content p { color: rgba(255, 255, 255, 0.6); }
|
||||||
|
.dark .exp-card .exp-content a { color: #d4b5ff; }
|
||||||
|
.dark .exp-card .exp-content a:hover { color: white; }
|
||||||
|
|
||||||
|
/* ────────────────────────────────────────────
|
||||||
|
Tech badges
|
||||||
|
──────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.exp-card .exp-tech {
|
||||||
|
background: #f3f4f6;
|
||||||
|
color: #6b7280;
|
||||||
|
border-color: #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-card .exp-tech {
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
color: rgba(255, 255, 255, 0.45);
|
||||||
|
border-color: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ────────────────────────────────────────────
|
||||||
|
Logo container
|
||||||
|
──────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.exp-logo {
|
||||||
|
background: #f9fafb;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-logo-fallback {
|
||||||
|
background: #f3f4f6;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-logo-fallback span {
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-logo {
|
||||||
|
background: white;
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-logo-fallback {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .exp-logo-fallback span {
|
||||||
|
color: rgba(255, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ────────────────────────────────────────────
|
||||||
|
Type badges
|
||||||
|
──────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.type-badge-blue { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
|
||||||
|
.type-badge-amber { background: #fffbeb; color: #b45309; border-color: #fde68a; }
|
||||||
|
.type-badge-emerald { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
|
||||||
|
.type-badge-pink { background: #fdf2f8; color: #be185d; border-color: #fbcfe8; }
|
||||||
|
.type-badge-purple { background: #faf5ff; color: #7e22ce; border-color: #e9d5ff; }
|
||||||
|
|
||||||
|
.dark .type-badge-blue { background: rgba(96, 165, 250, 0.15); color: #93c5fd; border-color: rgba(96, 165, 250, 0.2); }
|
||||||
|
.dark .type-badge-amber { background: rgba(251, 191, 36, 0.15); color: #fcd34d; border-color: rgba(251, 191, 36, 0.2); }
|
||||||
|
.dark .type-badge-emerald { background: rgba(52, 211, 153, 0.15); color: #6ee7b7; border-color: rgba(52, 211, 153, 0.2); }
|
||||||
|
.dark .type-badge-pink { background: rgba(244, 114, 182, 0.15); color: #f9a8d4; border-color: rgba(244, 114, 182, 0.2); }
|
||||||
|
.dark .type-badge-purple { background: rgba(168, 85, 247, 0.15); color: #d4b5ff; border-color: rgba(168, 85, 247, 0.2); }
|
||||||
|
|
||||||
|
/* ────────────────────────────────────────────
|
||||||
|
Type border (left for LTR, right for RTL)
|
||||||
|
──────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.type-border-blue { border-inline-start-color: #3b82f6; }
|
||||||
|
.type-border-amber { border-inline-start-color: #f59e0b; }
|
||||||
|
.type-border-emerald { border-inline-start-color: #10b981; }
|
||||||
|
.type-border-pink { border-inline-start-color: #ec4899; }
|
||||||
|
.type-border-purple { border-inline-start-color: #a855f7; }
|
||||||
|
|
||||||
|
.dark .type-border-blue { border-inline-start-color: rgba(96, 165, 250, 0.4); }
|
||||||
|
.dark .type-border-amber { border-inline-start-color: rgba(251, 191, 36, 0.4); }
|
||||||
|
.dark .type-border-emerald { border-inline-start-color: rgba(52, 211, 153, 0.4); }
|
||||||
|
.dark .type-border-pink { border-inline-start-color: rgba(244, 114, 182, 0.4); }
|
||||||
|
.dark .type-border-purple { border-inline-start-color: rgba(168, 85, 247, 0.4); }
|
||||||
Loading…
Add table
Reference in a new issue