mirror of
https://github.com/pepaskopec-blip/skopec.dev.git
synced 2026-10-27 07:04:33 +00:00
Add self-hosted services as project cards.
The homelab apps that stand on their own now show up on the Projects page, with a Services filter. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
12e472d750
commit
e2daab03e9
3 changed files with 550 additions and 10 deletions
1
llms.txt
1
llms.txt
|
|
@ -30,6 +30,7 @@ Local 10.0.0.x addresses work only on the home network or with Josef’s Tailsca
|
|||
- BatchGym
|
||||
- Graduately — https://github.com/pepaskopec-blip/Graduately
|
||||
- Terra
|
||||
- Jellyfin, Navidrome, Ollama, SearXNG, ConvertX, Pi-hole, Joplin, Immich — services from the homelab, also listed on the Projects page
|
||||
|
||||
## Friends
|
||||
- Martin Dvořák — https://dvorakmortonxd.dev
|
||||
|
|
|
|||
285
projects.html
285
projects.html
|
|
@ -3,11 +3,11 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Josef’s projects — skopec.dev, Proxmox homelab, Snake in Pygame, BatchGym, Graduately, and more.">
|
||||
<title>Projects — websites & games · Josef</title>
|
||||
<meta name="description" content="Josef’s projects — Graduately, skopec.dev, the Proxmox homelab, Jellyfin, Immich, Ollama, and more.">
|
||||
<title>Projects — websites, services & games · Josef</title>
|
||||
<link rel="canonical" href="https://skopec.dev/projects.html">
|
||||
<meta property="og:title" content="Projects — Josef">
|
||||
<meta property="og:description" content="Projects, websites, homelab, games, and school experiments.">
|
||||
<meta property="og:description" content="Projects, websites, homelab services, games, and school experiments.">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://skopec.dev/projects.html">
|
||||
<meta property="og:image" content="https://skopec.dev/og-image.jpg">
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<meta property="og:site_name" content="skopec.dev">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="Projects — Josef">
|
||||
<meta name="twitter:description" content="Websites, homelab, games, and school experiments.">
|
||||
<meta name="twitter:description" content="Websites, homelab services, games, and school experiments.">
|
||||
<meta name="twitter:image" content="https://skopec.dev/og-image.jpg">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
}
|
||||
})();
|
||||
</script>
|
||||
<link rel="stylesheet" href="style.css?v=20261023">
|
||||
<link rel="stylesheet" href="style.css?v=20261025">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
|
|
@ -85,12 +85,13 @@
|
|||
<div class="projects-hero-top">
|
||||
<div>
|
||||
<h1>Projects</h1>
|
||||
<p>Websites, the homelab, games, and school projects.</p>
|
||||
<p>Websites, self-hosted services, games, and school projects.</p>
|
||||
</div>
|
||||
<div class="project-filters" role="toolbar" aria-label="Filter projects">
|
||||
<button class="filter-chip is-active" type="button" data-filter="all">All <span>6</span></button>
|
||||
<button class="filter-chip is-active" type="button" data-filter="all">All <span>14</span></button>
|
||||
<button class="filter-chip" type="button" data-filter="apps">Apps & Web</button>
|
||||
<button class="filter-chip" type="button" data-filter="infra">Homelab & Program</button>
|
||||
<button class="filter-chip" type="button" data-filter="services">Services</button>
|
||||
<button class="filter-chip" type="button" data-filter="games">Games</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -347,10 +348,274 @@
|
|||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Jellyfin -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="https://jelly.skopec.dev" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>jellyfin</span>
|
||||
<span class="mock-svc-host">jelly.skopec.dev</span>
|
||||
</div>
|
||||
<div class="mock-posters" aria-hidden="true"><i></i><i></i><i></i><i></i></div>
|
||||
<div class="mock-now"><strong>Library</strong> · movies & TV on the NAS</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">Jellyfin</span>
|
||||
<span class="project-status">Movies & TV</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="https://jelly.skopec.dev" target="_blank" rel="noopener noreferrer">Jellyfin</a>
|
||||
</h3>
|
||||
<p>Movies and TV on my own server, with the library on the NAS. This is the one service with a public address — jelly.skopec.dev — the rest stay on the LAN or Tailscale.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Movies & TV</li>
|
||||
<li>jelly.skopec.dev</li>
|
||||
</ul>
|
||||
<a class="project-link" href="https://jelly.skopec.dev" target="_blank" rel="noopener noreferrer">Open Jellyfin →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Navidrome -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.103:4533" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>navidrome</span>
|
||||
<span class="mock-svc-host">10.0.0.103:4533</span>
|
||||
</div>
|
||||
<div class="mock-track">
|
||||
<div class="mock-album" aria-hidden="true"></div>
|
||||
<div>
|
||||
<div class="mock-track-title">Library</div>
|
||||
<div class="mock-track-by">Music · on the LAN</div>
|
||||
<div class="mock-bar"><i style="width: 46%"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">Navidrome</span>
|
||||
<span class="project-status">Music</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.103:4533" target="_blank" rel="noopener noreferrer">Navidrome</a>
|
||||
</h3>
|
||||
<p>Music from the homelab. Navidrome serves the library over the Subsonic API, so the same collection plays in the browser or in a phone app on my network.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Subsonic API</li>
|
||||
<li>Music</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.103:4533" target="_blank" rel="noopener noreferrer">Open Navidrome →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Ollama -->
|
||||
|
||||
|
||||
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.106:3000" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>ollama</span>
|
||||
<span class="mock-svc-host">10.0.0.106:3000</span>
|
||||
</div>
|
||||
<div class="mock-chat">
|
||||
<div class="mock-bubble ask">run it locally</div>
|
||||
<div class="mock-bubble reply">model on the homelab · stays on the network</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">Ollama</span>
|
||||
<span class="project-status">Local AI</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.106:3000" target="_blank" rel="noopener noreferrer">Ollama</a>
|
||||
</h3>
|
||||
<p>Local AI on the Proxmox box. Models run on my hardware, so a prompt stays on the network instead of going out to a hosted API.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Local LLM</li>
|
||||
<li>Private</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.106:3000" target="_blank" rel="noopener noreferrer">Open Ollama →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- SearXNG -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.104:8080" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>searxng</span>
|
||||
<span class="mock-svc-host">10.0.0.104:8080</span>
|
||||
</div>
|
||||
<div class="mock-search"><span class="mock-search-icon" aria-hidden="true">⌕</span><span>search the web</span></div>
|
||||
<div class="mock-search-meta"><span>general</span><span>images</span><span>news</span></div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">SearXNG</span>
|
||||
<span class="project-status">Search</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.104:8080" target="_blank" rel="noopener noreferrer">SearXNG</a>
|
||||
</h3>
|
||||
<p>Search I run myself. SearXNG asks other engines and brings the results back, without an account on a big search site.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Metasearch</li>
|
||||
<li>Private</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.104:8080" target="_blank" rel="noopener noreferrer">Open SearXNG →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- ConvertX -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.107:3000" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>convertx</span>
|
||||
<span class="mock-svc-host">10.0.0.107:3000</span>
|
||||
</div>
|
||||
<div class="mock-jobs">
|
||||
<div><span>image</span><em>→</em><span>png</span><b>local</b></div>
|
||||
<div><span>document</span><em>→</em><span>pdf</span><b>local</b></div>
|
||||
<div><span>audio</span><em>→</em><span>mp3</span><b>local</b></div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">ConvertX</span>
|
||||
<span class="project-status">File conversion</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.107:3000" target="_blank" rel="noopener noreferrer">ConvertX</a>
|
||||
</h3>
|
||||
<p>File conversion on the lab. When something needs another format, it converts here instead of uploading the file to a random website.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Files</li>
|
||||
<li>Private</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.107:3000" target="_blank" rel="noopener noreferrer">Open ConvertX →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Pi-hole -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.100/admin" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>pi-hole</span>
|
||||
<span class="mock-svc-host">10.0.0.100</span>
|
||||
</div>
|
||||
<div class="mock-stat">
|
||||
<strong>DNS</strong>
|
||||
<span>ads & trackers</span>
|
||||
</div>
|
||||
<div class="mock-bar"><i style="width: 38%"></i></div>
|
||||
<div class="mock-stat-rows">
|
||||
<div><span>Blocking</span><span>on</span></div>
|
||||
<div><span>Resolver</span><span>LAN</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">Pi-hole</span>
|
||||
<span class="project-status">DNS</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.100/admin" target="_blank" rel="noopener noreferrer">Pi-hole</a>
|
||||
</h3>
|
||||
<p>DNS for the network, with ad blocking in front of it. Devices that use this resolver drop a lot of ads and trackers before the page loads.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>DNS</li>
|
||||
<li>Ad blocking</li>
|
||||
<li>Network</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.100/admin" target="_blank" rel="noopener noreferrer">Open Pi-hole →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Joplin -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.111:22300" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>joplin</span>
|
||||
<span class="mock-svc-host">10.0.0.111:22300</span>
|
||||
</div>
|
||||
<div class="mock-notes">
|
||||
<div><i></i>Notes</div>
|
||||
<div><i></i>Sync server</div>
|
||||
<div><i></i>On the homelab</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">Joplin</span>
|
||||
<span class="project-status">Notes</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.111:22300" target="_blank" rel="noopener noreferrer">Joplin</a>
|
||||
</h3>
|
||||
<p>Notes that sync to the homelab. Joplin is the notebook, and the sync target is my own server instead of someone else’s cloud.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Notes</li>
|
||||
<li>Sync</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.111:22300" target="_blank" rel="noopener noreferrer">Open Joplin →</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Immich -->
|
||||
<li class="project-card" data-category="services">
|
||||
<a class="project-preview" href="http://10.0.0.109:2283" target="_blank" rel="noopener noreferrer" aria-hidden="true" tabindex="-1">
|
||||
<div class="mock-svc">
|
||||
<div class="mock-svc-top">
|
||||
<span class="mock-status-dot"></span>
|
||||
<span>immich</span>
|
||||
<span class="mock-svc-host">10.0.0.109:2283</span>
|
||||
</div>
|
||||
<div class="mock-photos" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i></div>
|
||||
<div class="mock-now"><strong>Library</strong> · photos on the NAS</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="project-card-body">
|
||||
<div class="project-card-meta">
|
||||
<span class="tag">Immich</span>
|
||||
<span class="project-status">Photos</span>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="http://10.0.0.109:2283" target="_blank" rel="noopener noreferrer">Immich</a>
|
||||
</h3>
|
||||
<p>Photo library on the NAS. Immich is where the pictures live, with a web UI instead of a shared folder.</p>
|
||||
<ul class="project-pills" aria-label="Details">
|
||||
<li>Self-hosted</li>
|
||||
<li>Photos</li>
|
||||
<li>NAS</li>
|
||||
</ul>
|
||||
<a class="project-link" href="http://10.0.0.109:2283" target="_blank" rel="noopener noreferrer">Open Immich →</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
274
style.css
274
style.css
|
|
@ -1722,6 +1722,280 @@ a:hover {
|
|||
font-weight: 650;
|
||||
}
|
||||
|
||||
/* Self-hosted service previews */
|
||||
.mock-svc {
|
||||
width: 100%;
|
||||
max-width: 24rem;
|
||||
padding: 0.9rem 1rem;
|
||||
background: var(--surface-solid);
|
||||
border: 1px solid var(--line-strong);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 14px 30px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.mock-svc-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 650;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.mock-svc-host {
|
||||
margin-left: auto;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.mock-posters {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.mock-posters i {
|
||||
display: block;
|
||||
aspect-ratio: 2 / 3;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(165deg, var(--accent) 0%, #24140f 78%);
|
||||
}
|
||||
|
||||
.mock-posters i:nth-child(2) {
|
||||
background: linear-gradient(200deg, #3d5a80 0%, #121820 80%);
|
||||
}
|
||||
|
||||
.mock-posters i:nth-child(3) {
|
||||
background: linear-gradient(150deg, #c45c26 0%, #1a120e 78%);
|
||||
}
|
||||
|
||||
.mock-posters i:nth-child(4) {
|
||||
background: linear-gradient(185deg, #6b4c7a 0%, #141820 80%);
|
||||
}
|
||||
|
||||
.mock-now {
|
||||
margin-top: 0.65rem;
|
||||
font-size: 0.72rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mock-now strong {
|
||||
color: var(--ink);
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.mock-track {
|
||||
display: grid;
|
||||
grid-template-columns: 3.1rem minmax(0, 1fr);
|
||||
gap: 0.7rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mock-album {
|
||||
width: 3.1rem;
|
||||
height: 3.1rem;
|
||||
border-radius: 2px;
|
||||
background:
|
||||
linear-gradient(145deg, transparent 42%, rgba(0, 0, 0, 0.28) 43% 57%, transparent 58%),
|
||||
linear-gradient(145deg, var(--accent) 0%, #1c2430 72%);
|
||||
}
|
||||
|
||||
.mock-track-title {
|
||||
font-weight: 700;
|
||||
font-size: 0.86rem;
|
||||
color: var(--ink);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.mock-track-by {
|
||||
margin: 0.12rem 0 0.45rem;
|
||||
font-size: 0.72rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mock-chat {
|
||||
display: grid;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.mock-bubble {
|
||||
max-width: 92%;
|
||||
padding: 0.42rem 0.6rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.4;
|
||||
color: var(--muted);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.mock-bubble.ask {
|
||||
margin-left: auto;
|
||||
color: var(--ink);
|
||||
border-color: rgba(255, 74, 28, 0.35);
|
||||
background: rgba(255, 74, 28, 0.1);
|
||||
}
|
||||
|
||||
.mock-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.55rem 0.7rem;
|
||||
border: 1px solid var(--line-strong);
|
||||
background: var(--bg);
|
||||
color: var(--ink-soft);
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.mock-search-icon {
|
||||
color: var(--accent);
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.mock-search-meta {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
margin-top: 0.65rem;
|
||||
font-size: 0.7rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mock-search-meta span:first-child {
|
||||
color: var(--accent-ink);
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.mock-jobs {
|
||||
display: grid;
|
||||
gap: 0.45rem;
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.mock-jobs div {
|
||||
display: grid;
|
||||
grid-template-columns: 5.2rem auto auto 1fr;
|
||||
gap: 0.45rem;
|
||||
align-items: center;
|
||||
color: var(--ink-soft);
|
||||
}
|
||||
|
||||
.mock-jobs em {
|
||||
font-style: normal;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.mock-jobs b {
|
||||
justify-self: end;
|
||||
font-weight: 650;
|
||||
font-size: 0.68rem;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mock-stat {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.mock-stat strong {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.35rem;
|
||||
font-weight: 750;
|
||||
letter-spacing: -0.03em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.mock-stat span {
|
||||
font-size: 0.72rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mock-stat-rows {
|
||||
display: grid;
|
||||
gap: 0.35rem;
|
||||
margin-top: 0.7rem;
|
||||
font-size: 0.72rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mock-stat-rows div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.mock-stat-rows div span:last-child {
|
||||
color: var(--ink-soft);
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.mock-notes {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.mock-notes div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
padding: 0.42rem 0;
|
||||
border-bottom: 1px solid var(--line);
|
||||
font-size: 0.8rem;
|
||||
color: var(--ink-soft);
|
||||
}
|
||||
|
||||
.mock-notes div:first-child {
|
||||
color: var(--ink);
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.mock-notes div:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.mock-notes i {
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 50%;
|
||||
background: var(--line-strong);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mock-notes div:first-child i {
|
||||
background: var(--accent);
|
||||
box-shadow: 0 0 8px var(--glow);
|
||||
}
|
||||
|
||||
.mock-photos {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.mock-photos i {
|
||||
display: block;
|
||||
aspect-ratio: 3 / 2;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(160deg, var(--line-strong), var(--glow-cool));
|
||||
}
|
||||
|
||||
.mock-photos i:nth-child(2),
|
||||
.mock-photos i:nth-child(6) {
|
||||
background: linear-gradient(200deg, rgba(255, 74, 28, 0.55), #1a140f);
|
||||
}
|
||||
|
||||
.mock-photos i:nth-child(3),
|
||||
.mock-photos i:nth-child(4) {
|
||||
background: linear-gradient(145deg, #3d5a80, #121820);
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5rem;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue