317 lines
8.9 KiB
Typst

#import "@preview/cmarker:0.1.6"
#let color-primary-blue = rgb("#133465")
#let color-table-header-gray = rgb("#575757")
#let color-table-alt-gray = rgb("#F3F4F6")
#let color-body-text = rgb("#133465")
#let color-footer-text-muted = rgb("#133465")
#let color-image-bg = rgb("#BFDBFE")
#let color-disclaimer-text = rgb("#FFFFFF")
#set heading(numbering: (..nums) => nums.pos().map(str).join("."))
#set heading(numbering: "1.1.")
#let default_page_layout(body) = {
set page(
paper: "a4",
margin: (x: 2cm, top: 2.5cm, bottom: 2cm), // Set margins for the page content
header: {
place(top, dx: -2cm, {
block(
fill: gradient.linear(rgb("#3578B7"), rgb("#133465")),
width: 21cm, // Full A4 page width
height: 1.5cm,
align(center + horizon, {
if "kryptonait_logo.png" in sys.inputs {
image("kryptonait_logo.png", height: 1.2cm)
} else {
text(fill: white, weight: "bold", "KRYPTONAIT")
}
})
)
})
},
footer: context {
grid(
columns: (auto, 1fr),
text(size: 08pt, fill: color-footer-text-muted, counter(page).display()),
align(right, text(
size: 09pt,
fill: color-footer-text-muted,
"© " + str(datetime.today().year()) + " Krypton AI Technologies. All rights reserved."
))
)
}
)
body
}
#let final_page_layout(body) = {
set page(
paper: "a4",
margin: (x: 2cm, top: 2.5cm, bottom: 2cm),
header: {
place(top, dx: -2cm, {
block(
fill: gradient.linear(rgb("#3578B7"), rgb("#133465")),
width: 21cm, // Full A4 page width
height: 1.5cm,
align(center + horizon, {
if "kryptonait_logo.png" in sys.inputs {
image("kryptonait_logo.png", height: 1.2cm)
} else {
text(fill: white, weight: "bold", "KRYPTONAIT")
}
})
)
})
},
footer: none // Remove the default footer for the last page
)
body
}
#let cover_page_top(body, subtitle: none, title: none) = {
set page(
margin: (x: 0cm, top: 0cm, bottom: 2cm),
footer: context {
box(width: 100%, inset: (x: 2cm), {
grid(
columns: (auto, 1fr),
text(size: 10pt, fill: color-footer-text-muted, counter(page).display()),
align(right, text(
size: 9pt,
fill: color-footer-text-muted,
"© " + str(datetime.today().year()) + " Krypton AI Technologies. All rights reserved."
))
)
})
}
)
block(
fill: gradient.linear(rgb("#3578B7"), rgb("#133465")),
width: 100%,
inset: (x: 1.5cm, y: 1.5cm),
{
grid(
columns: (auto, 2fr),
column-gutter: 1.5cm,
align: (horizon),
rect(
fill: white,
radius: 8pt,
inset: (x: 1cm, y: 0.5cm),
{
image("kryptonait_logo.png", width: 2cm)
}
),
{
set text(fill: white)
text(size: 24pt, weight: "bold")[KRYPTON AI TECHNOLOGIES]
v(0.2em)
}
)
}
)
if title != none {
v(9cm)
align(center, {
set text(fill: color-primary-blue)
underline(text(size: 28pt, weight: "bold", title))
if subtitle != none {
v(0.2cm)
text(size:24pt, weight: "bold", subtitle)
}
})
}
v(0.2cm)
pad(x: 2cm, body)
}
// --- Product Title Banner (Default Style) ---
#let product_heading_counter = counter("product_heading")
#let product_title(title, display_title: none, image_path: none) = {
product_heading_counter.step()
let visible_title = if display_title != none { display_title } else { title }
context {
let num = product_heading_counter.display()
let numbered_title = [#num #visible_title]
// Create a hidden heading for the outline.
// We disable the automatic numbering and put our own number in the title.
box(height: 0pt, clip: true, heading(numbering: none, numbered_title))
// Create the visible title block.
block(
fill: gradient.linear(rgb("#3578B7"), rgb("#133465")),
width: 100%,
inset: 0.5cm, // Apply uniform padding
{
// We already have the numbered_title
let title-text = text(fill: white, size: 22pt, weight: "bold", numbered_title)
if image_path != none and image_path in sys.inputs {
grid(
columns: (1fr, auto),
align(center + horizon, title-text),
align(right + horizon, {
rect(fill: color-image-bg, inset: 0.5cm, radius: 4pt, {
image(image_path, width: 3.5cm)
})
})
)
} else {
align(center, title-text)
}
}
)
}
v(1cm)
}
#let spec_table(v_lines: false, ..items) = {
let header-bg = color-table-header-gray
let alt-row-bg = color-table-alt-gray
let line-color = rgb("#e0e0e0")
// Filter out full-width string headers from data rows for zebra striping
let data-rows = items.pos().enumerate().filter(it => type(it.at(1)) == array)
block({
table(
columns: (auto, 1.5fr, 2fr),
stroke: none, // Disable all default lines
align: (center, left, left), // Set alignment for all columns
// Header Row
table.cell(fill: header-bg, inset: 12pt, text(fill: white, weight: "bold", "S. No")),
table.cell(fill: header-bg, inset: 12pt, text(fill: white, weight: "bold", "Components")),
table.cell(fill: header-bg, inset: 12pt, text(fill: white, weight: "bold", "Specifications")),
// Data Rows
..for (i, item) in items.pos().enumerate() {
if type(item) == str {
// This returns a single cell that spans columns, wrapped in an array
(table.cell(colspan: 3, fill: header-bg, inset: 12pt, align: center, text(fill: white, weight: "bold", item)),)
} else if type(item) == array {
// Determine row color for zebra striping
let data-row-index = data-rows.position(it => it.at(0) == i)
let row-color = if data-row-index != none and calc.rem(data-row-index, 2) == 1 { alt-row-bg } else { white }
// This returns an array of three cells, which the table will treat as one row.
(
table.cell(
fill: row-color, inset: 14pt,
stroke: (right: if v_lines { 0.5pt + line-color } else { none }),
item.at(0)
),
table.cell(
fill: row-color, inset: 14pt,
stroke: (right: if v_lines { 0.5pt + line-color } else { none }),
item.at(1)
),
table.cell(
fill: row-color, inset: 14pt,
item.at(2)
),
)
}
}
)
// Draw the final horizontal line
line(length: 100%, stroke: 0.5pt + line-color)
})
}
#let key_features(title: none, ..features) = {
set text(fill: color-primary-blue)
if title != none {
heading(level: 2, title)
} else {
heading(level: 2, "Key Features")
}
v(1em)
grid(
columns: (1fr, 1fr),
row-gutter: 1.2em,
column-gutter: 2cm,
..features.pos().map(item => [
#box(circle(radius: 3pt, fill: color-primary-blue))
#h(0.5em)
#text(fill: black, item)
#v(0.5em)
])
)
}
#let numbered_list(title: none, ..items) = {
set text(fill: color-primary-blue)
if title != none {
heading(level: 2, title)
}
v(1em)
for (i, item) in items.pos().enumerate() {
text(fill: black, str(i + 1) + ". " + item)
v(0.5em)
}
}
#let content_page() = {
outline(
title: text(16pt, weight: "bold", "Table of Contents"),
indent: 2em,
)
}
// --- Contact Footer Block ---
#let contact_footer() = {
// This component creates a full-bleed footer at the bottom of the page.
place(bottom, dx: -2cm, dy: 2cm, {
block(
width: 21cm, // Full A4 width
fill: gradient.linear(rgb("#3578B7"), rgb("#133465")),
inset: (x: 2cm, y: 2cm),
{
grid(
columns: (45fr, 30fr, 25fr),
gutter: 1cm,
align: (top + start),
{
set text(fill: white)
text(size: 14pt, weight: "bold")[Find out more]
v(0.5em)
link("https://kryptonait.com")[https://kryptonait.com]
v(2em)
text(size: 14pt, weight: "bold")[Krypton AI Technologies Private Limited]
v(0.5em)
text(size: 10pt)[H.NO. 9/A, Ishwar Nagar, BDA Colony, Bhopal, Madhya Pradesh, 462039]
v(1em)
text(size: 12pt)[Mob: +91 8109509889, +91 9424407601]
},
align(bottom, { text(size: 10pt, fill: color-disclaimer-text)[Krypton AI Tech. reserves the right, without notice, to make changes in product design specifications.] }),
align(center + horizon, {
image("kryptonait_logo.png", width: 4cm)
})
)
}
)
})
}