feat: polish review pack and homepage presentation
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 54s
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 54s
This commit is contained in:
parent
e828e59c12
commit
46bd1f71ae
@ -133,7 +133,7 @@ const canonicalPath = localizedPath('/platform/review-packs', locale);
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/70 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-neutral-200/70 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
@ -245,6 +245,49 @@ const canonicalPath = localizedPath('/platform/review-packs', locale);
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<figure
|
||||
class="mt-8 overflow-hidden rounded-3xl border border-neutral-300 bg-white shadow-sm dark:border-neutral-700 dark:bg-neutral-950/80"
|
||||
>
|
||||
<figcaption
|
||||
class="flex flex-wrap items-center justify-between gap-3 border-b border-neutral-200 bg-neutral-50 px-6 py-4 dark:border-neutral-800 dark:bg-neutral-900/70"
|
||||
>
|
||||
<span
|
||||
class="text-[11px] font-semibold tracking-[0.16em] text-neutral-500 uppercase dark:text-neutral-400"
|
||||
>
|
||||
{copy.decisionSampleBadge}
|
||||
</span>
|
||||
<span
|
||||
class="inline-flex items-center gap-2 rounded-full border border-yellow-200/60 bg-yellow-100/70 px-3 py-1 text-xs font-semibold text-yellow-800 dark:border-yellow-900/40 dark:bg-yellow-500/10 dark:text-yellow-300"
|
||||
>
|
||||
<span
|
||||
class="h-1.5 w-1.5 rounded-full bg-yellow-500 dark:bg-yellow-400"
|
||||
></span>
|
||||
{copy.decisionSampleStatusValue}
|
||||
</span>
|
||||
</figcaption>
|
||||
<div class="px-6 py-5">
|
||||
<h3
|
||||
class="text-base font-semibold text-balance text-neutral-800 dark:text-neutral-200"
|
||||
>
|
||||
{copy.decisionSampleTitle}
|
||||
</h3>
|
||||
<dl class="mt-4 grid gap-3">
|
||||
{
|
||||
copy.decisionSampleRows.map((row: any) => (
|
||||
<div class="grid gap-1 border-t border-neutral-100 pt-3 first:border-0 first:pt-0 sm:grid-cols-[7rem_1fr] sm:gap-4 dark:border-neutral-800">
|
||||
<dt class="text-xs font-semibold tracking-[0.14em] text-neutral-500 uppercase dark:text-neutral-400">
|
||||
{row.label}
|
||||
</dt>
|
||||
<dd class="text-sm leading-6 text-neutral-700 dark:text-neutral-300">
|
||||
{row.value}
|
||||
</dd>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
<div class="mt-8 grid gap-4 sm:grid-cols-2">
|
||||
{
|
||||
copy.decisionCards.map((card: any) => (
|
||||
@ -346,7 +389,7 @@ const canonicalPath = localizedPath('/platform/review-packs', locale);
|
||||
<div class="mt-8 grid gap-6 lg:grid-cols-2">
|
||||
{
|
||||
copy.audienceCards.map((card: any) => (
|
||||
<article class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 shadow-xs dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800">
|
||||
<article class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-neutral-200/70 p-6 shadow-xs dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800">
|
||||
<h3 class="text-2xl font-semibold text-balance text-neutral-800 dark:text-neutral-200">
|
||||
{card.title}
|
||||
</h3>
|
||||
@ -362,47 +405,77 @@ const canonicalPath = localizedPath('/platform/review-packs', locale);
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{copy.comparisonTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{copy.comparisonSubtitle}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-[2rem] bg-linear-to-br from-neutral-900 to-neutral-700 p-6 md:p-10 dark:from-neutral-950 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2 class="text-2xl font-bold text-balance text-neutral-50 md:text-3xl">
|
||||
{copy.comparisonTitle}
|
||||
</h2>
|
||||
<p class="mt-3 max-w-prose text-pretty text-neutral-300 md:text-lg">
|
||||
{copy.comparisonSubtitle}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-4">
|
||||
{
|
||||
copy.comparisonRows.map((row: any) => (
|
||||
<article class="rounded-[2rem] border border-neutral-300 bg-neutral-100/70 p-6 dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<h3 class="text-lg font-semibold text-neutral-800 dark:text-neutral-200">
|
||||
{row.title}
|
||||
</h3>
|
||||
<div class="mt-4 grid gap-4 md:grid-cols-2">
|
||||
<div class="rounded-2xl bg-neutral-200/80 p-5 dark:bg-neutral-900/70">
|
||||
<p class="text-xs font-semibold tracking-[0.18em] text-neutral-500 uppercase dark:text-neutral-400">
|
||||
<div class="mt-8 hidden gap-4 px-2 md:grid md:grid-cols-[9rem_1fr_1fr]">
|
||||
<span></span>
|
||||
<span
|
||||
class="text-xs font-semibold tracking-[0.18em] text-neutral-400 uppercase"
|
||||
>
|
||||
{copy.comparisonRawLabel}
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-semibold tracking-[0.18em] text-yellow-300 uppercase"
|
||||
>
|
||||
{copy.comparisonStoryLabel}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 grid gap-3">
|
||||
{
|
||||
copy.comparisonRows.map((row: any) => (
|
||||
<article class="grid gap-3 rounded-3xl border border-white/10 bg-white/[0.03] p-4 md:grid-cols-[9rem_1fr_1fr] md:items-stretch">
|
||||
<h3 class="self-center text-sm font-semibold text-neutral-100">
|
||||
{row.title}
|
||||
</h3>
|
||||
<div class="rounded-2xl bg-white/[0.04] p-4">
|
||||
<p class="text-[11px] font-semibold tracking-[0.18em] text-neutral-400 uppercase md:hidden">
|
||||
{copy.comparisonRawLabel}
|
||||
</p>
|
||||
<p class="mt-3 text-sm leading-6 text-neutral-600 dark:text-neutral-400">
|
||||
<p class="mt-2 text-sm leading-6 text-neutral-400 md:mt-0">
|
||||
{row.rawExport}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-2xl bg-yellow-100/80 p-5 dark:bg-yellow-500/10">
|
||||
<p class="text-xs font-semibold tracking-[0.18em] text-neutral-700 uppercase dark:text-yellow-200">
|
||||
<div class="rounded-2xl border border-yellow-400/30 bg-yellow-500/10 p-4">
|
||||
<p class="text-[11px] font-semibold tracking-[0.18em] text-yellow-300 uppercase md:hidden">
|
||||
{copy.comparisonStoryLabel}
|
||||
</p>
|
||||
<p class="mt-3 text-sm leading-6 text-neutral-700 dark:text-neutral-200">
|
||||
{row.reviewStory}
|
||||
</p>
|
||||
<div class="flex gap-2.5 md:items-start">
|
||||
<span class="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-yellow-400 text-neutral-900">
|
||||
<svg
|
||||
class="h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
</span>
|
||||
<p class="text-sm leading-6 text-neutral-100">
|
||||
{row.reviewStory}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ type NavItem = {
|
||||
>
|
||||
{/* Navigation container */}
|
||||
<nav
|
||||
class="relative mx-2 w-full rounded-[36px] border border-yellow-100/40 bg-yellow-50/60 px-4 py-3 backdrop-blur-md md:flex md:items-center md:justify-between md:px-6 md:py-0 lg:px-8 xl:mx-auto dark:border-neutral-700/40 dark:bg-neutral-800/80 dark:backdrop-blur-md"
|
||||
class="relative mx-2 w-full rounded-[36px] border border-yellow-100/60 bg-yellow-50/95 px-4 py-3 shadow-sm backdrop-blur-lg md:flex md:items-center md:justify-between md:px-6 md:py-0 lg:px-8 xl:mx-auto dark:border-neutral-700/60 dark:bg-neutral-900/95 dark:backdrop-blur-lg"
|
||||
aria-label="Global"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
|
||||
@ -9,17 +9,17 @@ interface Props {
|
||||
}
|
||||
// Define CSS classes for the hyperlink button
|
||||
const baseClasses =
|
||||
'inline-flex items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-center text-sm font-medium text-neutral-600 shadow-xs outline-hidden ring-zinc-500 focus-visible:ring-3 transition duration-300';
|
||||
const borderClasses = 'border border-neutral-200';
|
||||
const bgColorClasses = 'bg-neutral-300';
|
||||
'inline-flex items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-center text-sm font-medium text-neutral-800 shadow-xs outline-hidden ring-zinc-500 focus-visible:ring-3 transition duration-300';
|
||||
const borderClasses = 'border border-neutral-300';
|
||||
const bgColorClasses = 'bg-white';
|
||||
const hoverClasses =
|
||||
'hover:bg-neutral-400/50 hover:text-neutral-600 active:text-neutral-700';
|
||||
'hover:border-neutral-400 hover:bg-neutral-100 hover:text-neutral-900 active:bg-neutral-200';
|
||||
const disableClasses = 'disabled:pointer-events-none disabled:opacity-50';
|
||||
const fontSizeClasses = '2xl:text-base';
|
||||
const ringClasses = 'ring-zinc-500';
|
||||
|
||||
const darkClasses =
|
||||
'dark:border-neutral-700 dark:bg-zinc-700 dark:text-neutral-300 dark:ring-zinc-200 dark:hover:bg-zinc-600 dark:focus:outline-hidden';
|
||||
'dark:border-neutral-600 dark:bg-transparent dark:text-neutral-200 dark:ring-zinc-200 dark:hover:border-neutral-500 dark:hover:bg-neutral-800 dark:hover:text-white dark:focus:outline-hidden';
|
||||
---
|
||||
|
||||
{/* Styled hyperlink */}
|
||||
|
||||
@ -130,7 +130,7 @@ export const siteCopy: Record<Locale, any> = {
|
||||
eyebrow: 'Für MSPs',
|
||||
title: 'Wiederholbare Governance-Services pro Kunde aufbauen',
|
||||
content:
|
||||
'Zeige MSPs, wie Tenantial Reviews, Evidence, Drift und Accepted Risks pro Kundenumgebung in einen wiederholbaren Ablauf bringt.',
|
||||
'Reviews, Evidence, Drift und Accepted Risks werden pro Kundenumgebung zu einem wiederholbaren Ablauf, den dein Team verlässlich liefern kann.',
|
||||
cta: 'MSP-Use-Case ansehen',
|
||||
href: '/use-cases/msp',
|
||||
},
|
||||
@ -138,15 +138,15 @@ export const siteCopy: Record<Locale, any> = {
|
||||
eyebrow: 'Für interne IT',
|
||||
title: 'Kontrolle, Evidence und Audit-Kontext zusammenhalten',
|
||||
content:
|
||||
'Zeige internen Teams, wie Tenantial Policy-Drift, Change-Kontext, Backups und Review-Vorbereitung für Microsoft 365 lesbar macht.',
|
||||
'Policy-Drift, Change-Kontext, Backups und Review-Vorbereitung bleiben für Microsoft 365 an einem Ort lesbar und nachvollziehbar.',
|
||||
cta: 'Interne IT ansehen',
|
||||
href: '/use-cases/mittelstand',
|
||||
},
|
||||
{
|
||||
eyebrow: 'Für Reviews',
|
||||
title: 'Review Packs als Gesprächsgrundlage zeigen',
|
||||
title: 'Review Packs als Gesprächsgrundlage nutzen',
|
||||
content:
|
||||
'Zeige, wie Review Packs Evidence, Findings, Accepted Risks und nächste Schritte in eine customer-safe Review-Story übersetzen.',
|
||||
'Review Packs übersetzen Evidence, Findings, Accepted Risks und nächste Schritte in eine customer-safe Review-Story für jeden Termin.',
|
||||
cta: 'Review-Pack-Story ansehen',
|
||||
href: '/platform/review-packs',
|
||||
},
|
||||
@ -812,6 +812,31 @@ export const siteCopy: Record<Locale, any> = {
|
||||
'Sorgt dafür, dass Service-Review, Audit-Vorbereitung und Management-Gespräch auf dieselbe Story schauen.',
|
||||
},
|
||||
],
|
||||
decisionSampleBadge: 'Beispiel-Decision-Summary',
|
||||
decisionSampleTitle: 'Conditional Access: Legacy-Auth-Ausnahme',
|
||||
decisionSampleStatusLabel: 'Status',
|
||||
decisionSampleStatusValue: 'Akzeptiertes Risiko',
|
||||
decisionSampleRows: [
|
||||
{
|
||||
label: 'Begründung',
|
||||
value:
|
||||
'Altsystem benötigt Basic Auth bis zur geplanten Migration in Q3.',
|
||||
},
|
||||
{
|
||||
label: 'Auswirkung',
|
||||
value:
|
||||
'Erhöhte Angriffsfläche für ein klar abgegrenztes Servicekonto.',
|
||||
},
|
||||
{
|
||||
label: 'Evidence',
|
||||
value: 'Policy-Snapshot #142 · Change vom 12.05. · Finding F-07',
|
||||
},
|
||||
{
|
||||
label: 'Nächster Schritt',
|
||||
value:
|
||||
'Security prüft die Kompensationsmaßnahme vor dem nächsten Review.',
|
||||
},
|
||||
],
|
||||
boundaryTitle: 'Customer-safe Review statt interner Rohdetails',
|
||||
boundarySubtitle:
|
||||
'Die öffentliche Review-Pack-Story erklärt klar, was in eine kundenfähige Unterlage gehört und was standardmäßig intern bleibt.',
|
||||
@ -1337,7 +1362,7 @@ export const siteCopy: Record<Locale, any> = {
|
||||
eyebrow: 'For MSPs',
|
||||
title: 'Build repeatable governance services per customer',
|
||||
content:
|
||||
'Show MSP teams how Tenantial turns reviews, evidence, drift, and accepted risks into a repeatable customer workflow.',
|
||||
'Turn reviews, evidence, drift, and accepted risks into a repeatable workflow your team can deliver across every customer environment.',
|
||||
cta: 'Explore MSP use case',
|
||||
href: '/use-cases/msp',
|
||||
},
|
||||
@ -1345,15 +1370,15 @@ export const siteCopy: Record<Locale, any> = {
|
||||
eyebrow: 'For internal IT',
|
||||
title: 'Keep control, evidence, and audit context together',
|
||||
content:
|
||||
'Show internal teams how Tenantial makes policy drift, change context, backups, and review prep readable for Microsoft 365.',
|
||||
'Policy drift, change context, backups, and review prep stay readable in one place across your Microsoft 365 estate.',
|
||||
cta: 'Explore internal IT use case',
|
||||
href: '/use-cases/mittelstand',
|
||||
},
|
||||
{
|
||||
eyebrow: 'For reviews',
|
||||
title: 'Show review packs as the conversation baseline',
|
||||
title: 'Make review packs the conversation baseline',
|
||||
content:
|
||||
'Show how review packs translate evidence, findings, accepted risks, and next actions into a customer-safe review story.',
|
||||
'Review packs translate evidence, findings, accepted risks, and next actions into a customer-safe review story for every meeting.',
|
||||
cta: 'Explore review-pack story',
|
||||
href: '/platform/review-packs',
|
||||
},
|
||||
@ -2012,6 +2037,30 @@ export const siteCopy: Record<Locale, any> = {
|
||||
'Keeps service reviews, audit preparation, and management conversations anchored in the same story.',
|
||||
},
|
||||
],
|
||||
decisionSampleBadge: 'Example decision summary',
|
||||
decisionSampleTitle: 'Conditional Access: legacy auth exception',
|
||||
decisionSampleStatusLabel: 'Status',
|
||||
decisionSampleStatusValue: 'Accepted risk',
|
||||
decisionSampleRows: [
|
||||
{
|
||||
label: 'Reasoning',
|
||||
value:
|
||||
'Legacy system needs basic auth until the planned Q3 migration.',
|
||||
},
|
||||
{
|
||||
label: 'Impact',
|
||||
value: 'Elevated exposure for a clearly scoped service account.',
|
||||
},
|
||||
{
|
||||
label: 'Evidence',
|
||||
value: 'Policy snapshot #142 · change from May 12 · finding F-07',
|
||||
},
|
||||
{
|
||||
label: 'Next action',
|
||||
value:
|
||||
'Security reviews the compensating control before the next review.',
|
||||
},
|
||||
],
|
||||
boundaryTitle: 'Customer-safe review instead of internal raw detail',
|
||||
boundarySubtitle:
|
||||
'The public review-pack story should make it obvious what belongs in a customer-facing review and what stays internal by default.',
|
||||
@ -2451,7 +2500,7 @@ export const featuresByLocale: Record<Locale, Feature[]> = {
|
||||
heading: 'Backups & Versionen behalten',
|
||||
content:
|
||||
'Policy-Zustände nachvollziehbar sichern und Änderungen historisch vergleichbar machen.',
|
||||
svg: 'dashboard',
|
||||
svg: 'books',
|
||||
},
|
||||
{
|
||||
heading: 'Auditfähige Reviews vorbereiten',
|
||||
@ -2469,13 +2518,13 @@ export const featuresByLocale: Record<Locale, Feature[]> = {
|
||||
heading: 'Provider-Berechtigungen transparent machen',
|
||||
content:
|
||||
'Microsoft Graph und Provider-Zugriffe verständlich erklären, prüfen und capability-orientiert einordnen.',
|
||||
svg: 'frame',
|
||||
svg: 'groups',
|
||||
},
|
||||
{
|
||||
heading: 'Entscheidungen nachvollziehbar machen',
|
||||
content:
|
||||
'Findings, Exceptions, Accepted Risks und Follow-ups in einen prüfbaren Governance-Kontext bringen.',
|
||||
svg: 'dashboard',
|
||||
svg: 'checkCircle',
|
||||
},
|
||||
],
|
||||
en: [
|
||||
@ -2489,7 +2538,7 @@ export const featuresByLocale: Record<Locale, Feature[]> = {
|
||||
heading: 'Keep backups & versions',
|
||||
content:
|
||||
'Preserve policy states in a traceable way and compare changes historically.',
|
||||
svg: 'dashboard',
|
||||
svg: 'books',
|
||||
},
|
||||
{
|
||||
heading: 'Prepare audit-ready reviews',
|
||||
@ -2507,13 +2556,13 @@ export const featuresByLocale: Record<Locale, Feature[]> = {
|
||||
heading: 'Make provider permissions transparent',
|
||||
content:
|
||||
'Explain, verify, and classify Microsoft Graph and provider access by capability.',
|
||||
svg: 'frame',
|
||||
svg: 'groups',
|
||||
},
|
||||
{
|
||||
heading: 'Make decisions traceable',
|
||||
content:
|
||||
'Put findings, exceptions, accepted risks, and follow-ups into a reviewable governance context.',
|
||||
svg: 'dashboard',
|
||||
svg: 'checkCircle',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user