Course-specific presentation for work that should feel like a real file, terminal, or project artifact. Persistent values still use PathMX Input components; this Literate Component only owns their presentation.
<section class="project-artifact" data-artifact-type="{{ type }}">
<header class="project-artifact-bar">
<span class="project-artifact-type">{{ type }}</span>
<code>{{ file }}</code>
</header>
<div class="project-artifact-body">
<div class="project-artifact-heading">
<h4>{{ title }}</h4>
<p>{{ description }}</p>
</div>
<yield />
</div>
</section>
.project-artifact {
display: grid;
margin-block: 1.5rem;
overflow: clip;
border: 1px solid var(--pmx-color-border);
border-inline-start: 3px solid var(--pmx-color-accent);
background: color-mix(
in oklch,
var(--pmx-color-surface) 72%,
var(--pmx-color-bg)
);
box-shadow: 0 1rem 2.5rem color-mix(in oklch, black 18%, transparent);
}
.project-artifact-bar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
min-inline-size: 0;
padding: 0.5rem 0.75rem;
font-family: var(--pmx-font-mono);
font-size: 0.72rem;
letter-spacing: 0.05em;
color: var(--pmx-color-muted);
background: var(--pmx-color-bg);
}
.project-artifact-bar {
border-block-end: 1px solid var(--pmx-color-border);
}
.project-artifact-bar code {
overflow: hidden;
padding: 0;
border: 0;
color: var(--pmx-color-accent);
background: transparent;
text-overflow: ellipsis;
white-space: nowrap;
}
.project-artifact-type {
text-transform: uppercase;
}
.project-artifact-type::before {
content: "[";
}
.project-artifact-type::after {
content: "]";
}
.project-artifact-body {
display: grid;
gap: 1rem;
padding: clamp(1rem, 3vw, 1.5rem);
}
.project-artifact-heading {
display: grid;
gap: 0.3rem;
}
.project-artifact-heading h4,
.project-artifact-heading p {
margin: 0;
}
.project-artifact-heading h4 {
font-size: clamp(1rem, 2.5vw, 1.2rem);
}
.project-artifact-heading p {
max-inline-size: 60ch;
color: var(--pmx-color-muted);
font-size: 0.9rem;
line-height: 1.55;
}
.project-artifact .input-field {
display: grid;
gap: 0.45rem;
margin: 0;
font-family: var(--pmx-font-mono);
font-size: 0.78rem;
color: var(--pmx-color-muted);
}
.project-artifact :is(input[type="text"], textarea) {
box-sizing: border-box;
inline-size: 100%;
max-inline-size: none;
padding: 0.85rem 1rem;
border: 1px solid var(--pmx-color-border);
border-radius: 0;
color: var(--pmx-color-fg);
background: var(--pmx-color-bg);
font-family: var(--pmx-font-mono);
font-size: 0.95rem;
line-height: 1.6;
caret-color: var(--pmx-color-accent);
}
.project-artifact textarea {
min-block-size: 11rem;
resize: vertical;
tab-size: 2;
}
.project-artifact[data-artifact-type="markdown"] textarea,
.project-artifact[data-artifact-type="prompt"] textarea {
min-block-size: 18rem;
}
.project-artifact :is(input[type="text"], textarea):focus-visible {
border-color: var(--pmx-color-accent);
outline: 2px solid
color-mix(in oklch, var(--pmx-color-accent) 40%, transparent);
outline-offset: 2px;
}
@media (max-width: 36rem) {
.project-artifact-bar {
align-items: flex-start;
flex-direction: column;
gap: 0.2rem;
}
}